1e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao//===-- AsmPrinter.cpp - Common AsmPrinter code ---------------------------===//
2e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao//
3e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao//                     The LLVM Compiler Infrastructure
4e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao//
5e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao// This file is distributed under the University of Illinois Open Source
6e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao// License. See LICENSE.TXT for details.
7e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao//
8e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao//===----------------------------------------------------------------------===//
9e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao//
10e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao// This file implements the AsmPrinter class.
11e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao//
12e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao//===----------------------------------------------------------------------===//
13e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
14e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao#define DEBUG_TYPE "asm-printer"
15e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao#include "llvm/CodeGen/AsmPrinter.h"
16369c4a40cd8c97e1e513ec8c6eaeee26e6adfc9bDaniel Malea#if !defined(ANDROID_TARGET_BUILD) || defined(ANDROID_ENGINEERING_BUILD)
17a59a85f8dd03d52907019f1a4caaf7653b01b7d3Shih-wei Liao#   include "DwarfDebug.h"
18a59a85f8dd03d52907019f1a4caaf7653b01b7d3Shih-wei Liao#   include "DwarfException.h"
19369c4a40cd8c97e1e513ec8c6eaeee26e6adfc9bDaniel Malea#endif // !ANDROID_TARGET_BUILD || ANDROID_ENGINEERING_BUILD
20c3f0e98f40f1382870c679b6aef1c5d01540637fShih-wei Liao#include "llvm/DebugInfo.h"
21e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao#include "llvm/Module.h"
22e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao#include "llvm/CodeGen/GCMetadataPrinter.h"
23e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao#include "llvm/CodeGen/MachineConstantPool.h"
24e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao#include "llvm/CodeGen/MachineFrameInfo.h"
25e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao#include "llvm/CodeGen/MachineFunction.h"
26e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao#include "llvm/CodeGen/MachineJumpTableInfo.h"
27e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao#include "llvm/CodeGen/MachineLoopInfo.h"
28e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao#include "llvm/CodeGen/MachineModuleInfo.h"
29e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao#include "llvm/Analysis/ConstantFolding.h"
307abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao#include "llvm/MC/MCAsmInfo.h"
31e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao#include "llvm/MC/MCContext.h"
32e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao#include "llvm/MC/MCExpr.h"
33e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao#include "llvm/MC/MCInst.h"
34e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao#include "llvm/MC/MCSection.h"
35e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao#include "llvm/MC/MCStreamer.h"
36e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao#include "llvm/MC/MCSymbol.h"
37e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao#include "llvm/Target/Mangler.h"
38e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao#include "llvm/Target/TargetData.h"
39e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao#include "llvm/Target/TargetInstrInfo.h"
40e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao#include "llvm/Target/TargetLowering.h"
41e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao#include "llvm/Target/TargetLoweringObjectFile.h"
42a432997745f668e85e45826106430f69238b1d1eRafael Espindola#include "llvm/Target/TargetOptions.h"
43e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao#include "llvm/Target/TargetRegisterInfo.h"
449fc5cdf77c812aaa80419036de27576d45894d0dChris Lattner#include "llvm/Assembly/Writer.h"
45e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao#include "llvm/ADT/SmallString.h"
46e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao#include "llvm/ADT/Statistic.h"
47e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao#include "llvm/Support/ErrorHandling.h"
48e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao#include "llvm/Support/Format.h"
49d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene#include "llvm/Support/MathExtras.h"
507abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao#include "llvm/Support/Timer.h"
51e4454320b3cfffe926a487c33fbeb454366de2f8Shih-wei Liao#include <ctype.h>
52e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liaousing namespace llvm;
53e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
547abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liaostatic const char *DWARFGroupName = "DWARF Emission";
557abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liaostatic const char *DbgTimerName = "DWARF Debug Writer";
567abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liaostatic const char *EHTimerName = "DWARF Exception Writer";
577abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao
58e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei LiaoSTATISTIC(EmittedInsts, "Number of machine instrs printed");
59e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
60e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liaochar AsmPrinter::ID = 0;
617abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao
627abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liaotypedef DenseMap<GCStrategy*,GCMetadataPrinter*> gcp_map_type;
637abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liaostatic gcp_map_type &getGCMap(void *&P) {
647abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  if (P == 0)
657abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    P = new gcp_map_type();
667abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  return *(gcp_map_type*)P;
677abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao}
687abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao
697abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao
707516e9ec8193626b3bc987ea7eec3ec2e89e0f9eChris Lattner/// getGVAlignmentLog2 - Return the alignment to use for the specified global
717516e9ec8193626b3bc987ea7eec3ec2e89e0f9eChris Lattner/// value in log2 form.  This rounds up to the preferred alignment if possible
727516e9ec8193626b3bc987ea7eec3ec2e89e0f9eChris Lattner/// and legal.
737516e9ec8193626b3bc987ea7eec3ec2e89e0f9eChris Lattnerstatic unsigned getGVAlignmentLog2(const GlobalValue *GV, const TargetData &TD,
747516e9ec8193626b3bc987ea7eec3ec2e89e0f9eChris Lattner                                   unsigned InBits = 0) {
757516e9ec8193626b3bc987ea7eec3ec2e89e0f9eChris Lattner  unsigned NumBits = 0;
767516e9ec8193626b3bc987ea7eec3ec2e89e0f9eChris Lattner  if (const GlobalVariable *GVar = dyn_cast<GlobalVariable>(GV))
777516e9ec8193626b3bc987ea7eec3ec2e89e0f9eChris Lattner    NumBits = TD.getPreferredAlignmentLog(GVar);
7883d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
797516e9ec8193626b3bc987ea7eec3ec2e89e0f9eChris Lattner  // If InBits is specified, round it to it.
807516e9ec8193626b3bc987ea7eec3ec2e89e0f9eChris Lattner  if (InBits > NumBits)
817516e9ec8193626b3bc987ea7eec3ec2e89e0f9eChris Lattner    NumBits = InBits;
8283d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
837516e9ec8193626b3bc987ea7eec3ec2e89e0f9eChris Lattner  // If the GV has a specified alignment, take it into account.
847516e9ec8193626b3bc987ea7eec3ec2e89e0f9eChris Lattner  if (GV->getAlignment() == 0)
857516e9ec8193626b3bc987ea7eec3ec2e89e0f9eChris Lattner    return NumBits;
8683d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
877516e9ec8193626b3bc987ea7eec3ec2e89e0f9eChris Lattner  unsigned GVAlign = Log2_32(GV->getAlignment());
8883d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
897516e9ec8193626b3bc987ea7eec3ec2e89e0f9eChris Lattner  // If the GVAlign is larger than NumBits, or if we are required to obey
907516e9ec8193626b3bc987ea7eec3ec2e89e0f9eChris Lattner  // NumBits because the GV has an assigned section, obey it.
917516e9ec8193626b3bc987ea7eec3ec2e89e0f9eChris Lattner  if (GVAlign > NumBits || GV->hasSection())
927516e9ec8193626b3bc987ea7eec3ec2e89e0f9eChris Lattner    NumBits = GVAlign;
937516e9ec8193626b3bc987ea7eec3ec2e89e0f9eChris Lattner  return NumBits;
947516e9ec8193626b3bc987ea7eec3ec2e89e0f9eChris Lattner}
957516e9ec8193626b3bc987ea7eec3ec2e89e0f9eChris Lattner
967516e9ec8193626b3bc987ea7eec3ec2e89e0f9eChris Lattner
977516e9ec8193626b3bc987ea7eec3ec2e89e0f9eChris Lattner
987516e9ec8193626b3bc987ea7eec3ec2e89e0f9eChris Lattner
997abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei LiaoAsmPrinter::AsmPrinter(TargetMachine &tm, MCStreamer &Streamer)
1007569322765651f19eea0609fb082e6b267d5d2b5Owen Anderson  : MachineFunctionPass(ID),
1017abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    TM(tm), MAI(tm.getMCAsmInfo()),
1027abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    OutContext(Streamer.getContext()),
1037abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    OutStreamer(Streamer),
1047abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    LastMI(0), LastFn(0), Counter(~0U), SetCounter(0) {
1057abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  DD = 0; DE = 0; MMI = 0; LI = 0;
106d55a2664f9493a4c3be242a75d339fac0ebe2e21Hal Finkel  CurrentFnSym = CurrentFnSymForSize = 0;
1077abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  GCMetadataPrinters = 0;
108e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  VerboseAsm = Streamer.isVerboseAsm();
109e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao}
110e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
111e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei LiaoAsmPrinter::~AsmPrinter() {
1127abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  assert(DD == 0 && DE == 0 && "Debug/EH info didn't get finalized");
11383d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
1147abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  if (GCMetadataPrinters != 0) {
1157abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    gcp_map_type &GCMap = getGCMap(GCMetadataPrinters);
11683d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
1177abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    for (gcp_map_type::iterator I = GCMap.begin(), E = GCMap.end(); I != E; ++I)
1187abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao      delete I->second;
1197abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    delete &GCMap;
1207abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    GCMetadataPrinters = 0;
1217abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  }
12283d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
123e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  delete &OutStreamer;
124e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao}
125e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
126e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao/// getFunctionNumber - Return a unique ID for the current function.
127e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao///
128e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liaounsigned AsmPrinter::getFunctionNumber() const {
129e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  return MF->getFunctionNumber();
130e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao}
131e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
1327abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liaoconst TargetLoweringObjectFile &AsmPrinter::getObjFileLowering() const {
133e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  return TM.getTargetLowering()->getObjFileLowering();
134e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao}
135e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
1367abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao
1377abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao/// getTargetData - Return information about data layout.
1387abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liaoconst TargetData &AsmPrinter::getTargetData() const {
1397abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  return *TM.getTargetData();
1407abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao}
1417abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao
142e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao/// getCurrentSection() - Return the current section we are emitting to.
143e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liaoconst MCSection *AsmPrinter::getCurrentSection() const {
144e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  return OutStreamer.getCurrentSection();
145e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao}
146e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
147e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
1487abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao
149e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liaovoid AsmPrinter::getAnalysisUsage(AnalysisUsage &AU) const {
150e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  AU.setPreservesAll();
151e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  MachineFunctionPass::getAnalysisUsage(AU);
1527abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  AU.addRequired<MachineModuleInfo>();
153e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  AU.addRequired<GCModuleInfo>();
1547abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  if (isVerbose())
155e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    AU.addRequired<MachineLoopInfo>();
156e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao}
157e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
158e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liaobool AsmPrinter::doInitialization(Module &M) {
1597abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  MMI = getAnalysisIfAvailable<MachineModuleInfo>();
1607abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  MMI->AnalyzeModule(M);
1617abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao
162e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  // Initialize TargetLoweringObjectFile.
163e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  const_cast<TargetLoweringObjectFile&>(getObjFileLowering())
164e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    .Initialize(OutContext, TM);
16583d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
1667abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  Mang = new Mangler(OutContext, *TM.getTargetData());
16783d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
168e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  // Allow the target to emit any magic that it wants at the start of the file.
169e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  EmitStartOfAsmFile(M);
170e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
171e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  // Very minimal debug info. It is ignored if we emit actual debug info. If we
172e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  // don't, this at least helps the user find where a global came from.
173e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  if (MAI->hasSingleParameterDotFile()) {
174e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    // .file "foo.c"
175e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    OutStreamer.EmitFileDirective(M.getModuleIdentifier());
176e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  }
177e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
178e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  GCModuleInfo *MI = getAnalysisIfAvailable<GCModuleInfo>();
179e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  assert(MI && "AsmPrinter didn't require GCModuleInfo?");
180e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  for (GCModuleInfo::iterator I = MI->begin(), E = MI->end(); I != E; ++I)
181e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    if (GCMetadataPrinter *MP = GetOrCreateGCPrinter(*I))
1827abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao      MP->beginAssembly(*this);
183e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
1847abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  // Emit module-level inline asm if it exists.
1857abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  if (!M.getModuleInlineAsm().empty()) {
1867abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    OutStreamer.AddComment("Start of file scope inline assembly");
1877abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    OutStreamer.AddBlankLine();
188a38941d458273946594d3592ed5debdc9730db08Chris Lattner    EmitInlineAsm(M.getModuleInlineAsm()+"\n");
1897abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    OutStreamer.AddComment("End of file scope inline assembly");
1907abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    OutStreamer.AddBlankLine();
1917abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  }
1927abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao
193369c4a40cd8c97e1e513ec8c6eaeee26e6adfc9bDaniel Malea#if !defined(ANDROID_TARGET_BUILD) || defined(ANDROID_ENGINEERING_BUILD)
1947abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  if (MAI->doesSupportDebugInformation())
1957abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    DD = new DwarfDebug(this, &M);
196d7e8ddc5012d22398eba6b8094e2fd7821bac9ccAnton Korobeynikov
1972d57a6470181e7cc6396caae69e045cd0549d10eRafael Espindola  switch (MAI->getExceptionHandlingType()) {
1982d57a6470181e7cc6396caae69e045cd0549d10eRafael Espindola  case ExceptionHandling::None:
1992d57a6470181e7cc6396caae69e045cd0549d10eRafael Espindola    return false;
2002d57a6470181e7cc6396caae69e045cd0549d10eRafael Espindola  case ExceptionHandling::SjLj:
2012d57a6470181e7cc6396caae69e045cd0549d10eRafael Espindola  case ExceptionHandling::DwarfCFI:
2022d57a6470181e7cc6396caae69e045cd0549d10eRafael Espindola    DE = new DwarfCFIException(this);
2032d57a6470181e7cc6396caae69e045cd0549d10eRafael Espindola    return false;
2042d57a6470181e7cc6396caae69e045cd0549d10eRafael Espindola  case ExceptionHandling::ARM:
2052d57a6470181e7cc6396caae69e045cd0549d10eRafael Espindola    DE = new ARMException(this);
2062d57a6470181e7cc6396caae69e045cd0549d10eRafael Espindola    return false;
207d652b1368b1e381382951f450e5eeca870d91dd6Charles Davis  case ExceptionHandling::Win64:
208d652b1368b1e381382951f450e5eeca870d91dd6Charles Davis    DE = new Win64Exception(this);
209d652b1368b1e381382951f450e5eeca870d91dd6Charles Davis    return false;
2102d57a6470181e7cc6396caae69e045cd0549d10eRafael Espindola  }
211907af0f20f58f2ea26da7ea64e1f094cd6880db7Nowar Gu#else
212907af0f20f58f2ea26da7ea64e1f094cd6880db7Nowar Gu  return false;
213369c4a40cd8c97e1e513ec8c6eaeee26e6adfc9bDaniel Malea#endif // !ANDROID_TARGET_BUILD || ANDROID_ENGINEERING_BUILD
214e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
2152d57a6470181e7cc6396caae69e045cd0549d10eRafael Espindola  llvm_unreachable("Unknown exception type.");
216e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao}
217e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
218e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liaovoid AsmPrinter::EmitLinkage(unsigned Linkage, MCSymbol *GVSym) const {
219e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  switch ((GlobalValue::LinkageTypes)Linkage) {
220e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  case GlobalValue::CommonLinkage:
221e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  case GlobalValue::LinkOnceAnyLinkage:
222e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  case GlobalValue::LinkOnceODRLinkage:
22332811bef956e0fae4329e6515420d85f7e510660Bill Wendling  case GlobalValue::LinkOnceODRAutoHideLinkage:
224e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  case GlobalValue::WeakAnyLinkage:
225e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  case GlobalValue::WeakODRLinkage:
226f823966e3fdbd57c5f85cc1ce856c7435c474bf4Bill Wendling  case GlobalValue::LinkerPrivateWeakLinkage:
227e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    if (MAI->getWeakDefDirective() != 0) {
228e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      // .globl _foo
229e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Global);
23001085e6f25479f3e4075a9c60d028e7a462410bbBill Wendling
23101085e6f25479f3e4075a9c60d028e7a462410bbBill Wendling      if ((GlobalValue::LinkageTypes)Linkage !=
23232811bef956e0fae4329e6515420d85f7e510660Bill Wendling          GlobalValue::LinkOnceODRAutoHideLinkage)
23301085e6f25479f3e4075a9c60d028e7a462410bbBill Wendling        // .weak_definition _foo
23401085e6f25479f3e4075a9c60d028e7a462410bbBill Wendling        OutStreamer.EmitSymbolAttribute(GVSym, MCSA_WeakDefinition);
23501085e6f25479f3e4075a9c60d028e7a462410bbBill Wendling      else
23601085e6f25479f3e4075a9c60d028e7a462410bbBill Wendling        OutStreamer.EmitSymbolAttribute(GVSym, MCSA_WeakDefAutoPrivate);
237f01b62dabc0372b5cf4525272fba263e6589f066Duncan Sands    } else if (MAI->getLinkOnceDirective() != 0) {
238e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      // .globl _foo
239e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Global);
240f01b62dabc0372b5cf4525272fba263e6589f066Duncan Sands      //NOTE: linkonce is handled by the section the symbol was assigned to.
241e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    } else {
242e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      // .weak _foo
243e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Weak);
244e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    }
245e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    break;
246e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  case GlobalValue::DLLExportLinkage:
247e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  case GlobalValue::AppendingLinkage:
248e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    // FIXME: appending linkage variables should go into a section of
249e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    // their name or something.  For now, just emit them as external.
250e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  case GlobalValue::ExternalLinkage:
251e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    // If external or appending, declare as a global symbol.
252e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    // .globl _foo
253e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Global);
254e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    break;
255e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  case GlobalValue::PrivateLinkage:
256e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  case GlobalValue::InternalLinkage:
25773b3a72bb9b93a3d33b490fd415c2c186a4f2035Bill Wendling  case GlobalValue::LinkerPrivateLinkage:
258e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    break;
259e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  default:
260e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    llvm_unreachable("Unknown linkage type!");
261e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  }
262e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao}
263e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
264e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
265e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao/// EmitGlobalVariable - Emit the specified global variable to the .s file.
266e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liaovoid AsmPrinter::EmitGlobalVariable(const GlobalVariable *GV) {
26784397472364ac3ce3b5dbcc1e6aa93e9a584c32fRafael Espindola  if (GV->hasInitializer()) {
26884397472364ac3ce3b5dbcc1e6aa93e9a584c32fRafael Espindola    // Check to see if this is a special global used by LLVM, if so, emit it.
26984397472364ac3ce3b5dbcc1e6aa93e9a584c32fRafael Espindola    if (EmitSpecialLLVMGlobal(GV))
27084397472364ac3ce3b5dbcc1e6aa93e9a584c32fRafael Espindola      return;
271e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
27284397472364ac3ce3b5dbcc1e6aa93e9a584c32fRafael Espindola    if (isVerbose()) {
27384397472364ac3ce3b5dbcc1e6aa93e9a584c32fRafael Espindola      WriteAsOperand(OutStreamer.GetCommentOS(), GV,
27484397472364ac3ce3b5dbcc1e6aa93e9a584c32fRafael Espindola                     /*PrintType=*/false, GV->getParent());
27584397472364ac3ce3b5dbcc1e6aa93e9a584c32fRafael Espindola      OutStreamer.GetCommentOS() << '\n';
27684397472364ac3ce3b5dbcc1e6aa93e9a584c32fRafael Espindola    }
2773fe79fd1451918e661b45268de5610b9657ae72cEric Christopher  }
27883d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
2797abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  MCSymbol *GVSym = Mang->getSymbol(GV);
280348d542199f83418481bde6eba1c94f6fdb45b85Chad Rosier  EmitVisibility(GVSym, GV->getVisibility(), !GV->isDeclaration());
281e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
28284397472364ac3ce3b5dbcc1e6aa93e9a584c32fRafael Espindola  if (!GV->hasInitializer())   // External globals require no extra code.
28384397472364ac3ce3b5dbcc1e6aa93e9a584c32fRafael Espindola    return;
28484397472364ac3ce3b5dbcc1e6aa93e9a584c32fRafael Espindola
285e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  if (MAI->hasDotTypeDotSizeDirective())
286e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    OutStreamer.EmitSymbolAttribute(GVSym, MCSA_ELF_TypeObject);
28783d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
288e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  SectionKind GVKind = TargetLoweringObjectFile::getKindForGlobal(GV, TM);
289e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
290e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  const TargetData *TD = TM.getTargetData();
2917516e9ec8193626b3bc987ea7eec3ec2e89e0f9eChris Lattner  uint64_t Size = TD->getTypeAllocSize(GV->getType()->getElementType());
29283d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
2937abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  // If the alignment is specified, we *must* obey it.  Overaligning a global
2947abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  // with a specified alignment is a prompt way to break globals emitted to
2957abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  // sections and expected to be contiguous (e.g. ObjC metadata).
2967516e9ec8193626b3bc987ea7eec3ec2e89e0f9eChris Lattner  unsigned AlignLog = getGVAlignmentLog2(GV, *TD);
29783d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
298e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  // Handle common and BSS local symbols (.lcomm).
299e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  if (GVKind.isCommon() || GVKind.isBSSLocal()) {
300e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    if (Size == 0) Size = 1;   // .comm Foo, 0 is undefined, avoid it.
30136a16015ac108e2f0dd2d6d96a6d364bc74c50d7Benjamin Kramer    unsigned Align = 1 << AlignLog;
30283d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
303e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    // Handle common symbols.
304e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    if (GVKind.isCommon()) {
30582f9a8eae4cb689b5fe40faf35c16279164e2fdbChris Lattner      if (!getObjFileLowering().getCommDirectiveSupportsAlignment())
30682f9a8eae4cb689b5fe40faf35c16279164e2fdbChris Lattner        Align = 0;
30783d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
308e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      // .comm _foo, 42, 4
30982f9a8eae4cb689b5fe40faf35c16279164e2fdbChris Lattner      OutStreamer.EmitCommonSymbol(GVSym, Size, Align);
310e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      return;
311e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    }
31283d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
313e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    // Handle local BSS symbols.
314e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    if (MAI->hasMachoZeroFillDirective()) {
315e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      const MCSection *TheSection =
316e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao        getObjFileLowering().SectionForGlobal(GV, GVKind, Mang, TM);
317e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      // .zerofill __DATA, __bss, _foo, 400, 5
31836a16015ac108e2f0dd2d6d96a6d364bc74c50d7Benjamin Kramer      OutStreamer.EmitZerofill(TheSection, GVSym, Size, Align);
319e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      return;
320e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    }
32183d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
322a9e37c5eaf79c3a32f2921536fb7e12514e86fb2Benjamin Kramer    if (Align == 1 ||
323a9e37c5eaf79c3a32f2921536fb7e12514e86fb2Benjamin Kramer        MAI->getLCOMMDirectiveAlignmentType() != LCOMM::NoAlignment) {
324e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      // .lcomm _foo, 42
32536a16015ac108e2f0dd2d6d96a6d364bc74c50d7Benjamin Kramer      OutStreamer.EmitLocalCommonSymbol(GVSym, Size, Align);
326e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      return;
327e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    }
32882f9a8eae4cb689b5fe40faf35c16279164e2fdbChris Lattner
32982f9a8eae4cb689b5fe40faf35c16279164e2fdbChris Lattner    if (!getObjFileLowering().getCommDirectiveSupportsAlignment())
33082f9a8eae4cb689b5fe40faf35c16279164e2fdbChris Lattner      Align = 0;
33183d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
332e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    // .local _foo
333e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Local);
334e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    // .comm _foo, 42, 4
33582f9a8eae4cb689b5fe40faf35c16279164e2fdbChris Lattner    OutStreamer.EmitCommonSymbol(GVSym, Size, Align);
336e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    return;
337e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  }
33883d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
339e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  const MCSection *TheSection =
340e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    getObjFileLowering().SectionForGlobal(GV, GVKind, Mang, TM);
341e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
342e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  // Handle the zerofill directive on darwin, which is a special form of BSS
343e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  // emission.
344e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  if (GVKind.isBSSExtern() && MAI->hasMachoZeroFillDirective()) {
3450631a92272bef91243ddfe9cc5fa0ca41360c98fChris Lattner    if (Size == 0) Size = 1;  // zerofill of 0 bytes is undefined.
34683d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
347e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    // .globl _foo
348e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    OutStreamer.EmitSymbolAttribute(GVSym, MCSA_Global);
349e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    // .zerofill __DATA, __common, _foo, 400, 5
350e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    OutStreamer.EmitZerofill(TheSection, GVSym, Size, 1 << AlignLog);
351e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    return;
352e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  }
35383d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
354fdc794a7f748a2b83c8a2e32378111785ad53146Eric Christopher  // Handle thread local data for mach-o which requires us to output an
355fdc794a7f748a2b83c8a2e32378111785ad53146Eric Christopher  // additional structure of data and mangle the original symbol so that we
356fdc794a7f748a2b83c8a2e32378111785ad53146Eric Christopher  // can reference it later.
357c1f3acb7b71a00f9a95bbbcf4de1cd02c805ac8aChris Lattner  //
358c1f3acb7b71a00f9a95bbbcf4de1cd02c805ac8aChris Lattner  // TODO: This should become an "emit thread local global" method on TLOF.
359c1f3acb7b71a00f9a95bbbcf4de1cd02c805ac8aChris Lattner  // All of this macho specific stuff should be sunk down into TLOFMachO and
360c1f3acb7b71a00f9a95bbbcf4de1cd02c805ac8aChris Lattner  // stuff like "TLSExtraDataSection" should no longer be part of the parent
361c1f3acb7b71a00f9a95bbbcf4de1cd02c805ac8aChris Lattner  // TLOF class.  This will also make it more obvious that stuff like
362c1f3acb7b71a00f9a95bbbcf4de1cd02c805ac8aChris Lattner  // MCStreamer::EmitTBSSSymbol is macho specific and only called from macho
363c1f3acb7b71a00f9a95bbbcf4de1cd02c805ac8aChris Lattner  // specific code.
364fdc794a7f748a2b83c8a2e32378111785ad53146Eric Christopher  if (GVKind.isThreadLocal() && MAI->hasMachoTBSSDirective()) {
3650f986f6715496c159b8dc0b2b09f531b6416d3eeEric Christopher    // Emit the .tbss symbol
36683d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach    MCSymbol *MangSym =
3670f986f6715496c159b8dc0b2b09f531b6416d3eeEric Christopher      OutContext.GetOrCreateSymbol(GVSym->getName() + Twine("$tlv$init"));
36883d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
369fdc794a7f748a2b83c8a2e32378111785ad53146Eric Christopher    if (GVKind.isThreadBSS())
370fdc794a7f748a2b83c8a2e32378111785ad53146Eric Christopher      OutStreamer.EmitTBSSSymbol(TheSection, MangSym, Size, 1 << AlignLog);
371fdc794a7f748a2b83c8a2e32378111785ad53146Eric Christopher    else if (GVKind.isThreadData()) {
372fdc794a7f748a2b83c8a2e32378111785ad53146Eric Christopher      OutStreamer.SwitchSection(TheSection);
373fdc794a7f748a2b83c8a2e32378111785ad53146Eric Christopher
37483d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach      EmitAlignment(AlignLog, GV);
375fdc794a7f748a2b83c8a2e32378111785ad53146Eric Christopher      OutStreamer.EmitLabel(MangSym);
37683d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
377fdc794a7f748a2b83c8a2e32378111785ad53146Eric Christopher      EmitGlobalConstant(GV->getInitializer());
378fdc794a7f748a2b83c8a2e32378111785ad53146Eric Christopher    }
37983d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
3800f986f6715496c159b8dc0b2b09f531b6416d3eeEric Christopher    OutStreamer.AddBlankLine();
38183d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
3820f986f6715496c159b8dc0b2b09f531b6416d3eeEric Christopher    // Emit the variable struct for the runtime.
38383d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach    const MCSection *TLVSect
3840f986f6715496c159b8dc0b2b09f531b6416d3eeEric Christopher      = getObjFileLowering().getTLSExtraDataSection();
38583d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
3860f986f6715496c159b8dc0b2b09f531b6416d3eeEric Christopher    OutStreamer.SwitchSection(TLVSect);
3870f986f6715496c159b8dc0b2b09f531b6416d3eeEric Christopher    // Emit the linkage here.
3880f986f6715496c159b8dc0b2b09f531b6416d3eeEric Christopher    EmitLinkage(GV->getLinkage(), GVSym);
3890f986f6715496c159b8dc0b2b09f531b6416d3eeEric Christopher    OutStreamer.EmitLabel(GVSym);
39083d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
3910f986f6715496c159b8dc0b2b09f531b6416d3eeEric Christopher    // Three pointers in size:
3920f986f6715496c159b8dc0b2b09f531b6416d3eeEric Christopher    //   - __tlv_bootstrap - used to make sure support exists
3930f986f6715496c159b8dc0b2b09f531b6416d3eeEric Christopher    //   - spare pointer, used when mapped by the runtime
3940f986f6715496c159b8dc0b2b09f531b6416d3eeEric Christopher    //   - pointer to mangled symbol above with initializer
3950f986f6715496c159b8dc0b2b09f531b6416d3eeEric Christopher    unsigned PtrSize = TD->getPointerSizeInBits()/8;
396dbf4b2d0533807a789d38f850f5e6cb00d1d3d1fEric Christopher    OutStreamer.EmitSymbolValue(GetExternalSymbolSymbol("_tlv_bootstrap"),
3970f986f6715496c159b8dc0b2b09f531b6416d3eeEric Christopher                          PtrSize, 0);
3980f986f6715496c159b8dc0b2b09f531b6416d3eeEric Christopher    OutStreamer.EmitIntValue(0, PtrSize, 0);
3990f986f6715496c159b8dc0b2b09f531b6416d3eeEric Christopher    OutStreamer.EmitSymbolValue(MangSym, PtrSize, 0);
40083d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
4010f986f6715496c159b8dc0b2b09f531b6416d3eeEric Christopher    OutStreamer.AddBlankLine();
4022d4ea3e6925c65e2a182ea83c3e7d1aab11cc0daEric Christopher    return;
4032d4ea3e6925c65e2a182ea83c3e7d1aab11cc0daEric Christopher  }
404e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
405e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  OutStreamer.SwitchSection(TheSection);
406e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
407e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  EmitLinkage(GV->getLinkage(), GVSym);
408e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  EmitAlignment(AlignLog, GV);
409e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
410e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  OutStreamer.EmitLabel(GVSym);
411e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
412e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  EmitGlobalConstant(GV->getInitializer());
413e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
414e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  if (MAI->hasDotTypeDotSizeDirective())
415e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    // .size foo, 42
416e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    OutStreamer.EmitELFSize(GVSym, MCConstantExpr::Create(Size, OutContext));
41783d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
418e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  OutStreamer.AddBlankLine();
419e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao}
420e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
421e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao/// EmitFunctionHeader - This method emits the header for the current
422e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao/// function.
423e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liaovoid AsmPrinter::EmitFunctionHeader() {
424e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  // Print out constants referenced by the function
425e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  EmitConstantPool();
42683d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
427e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  // Print the 'header' of function.
428e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  const Function *F = MF->getFunction();
429e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
430e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(F, Mang, TM));
431e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  EmitVisibility(CurrentFnSym, F->getVisibility());
432e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
433e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  EmitLinkage(F->getLinkage(), CurrentFnSym);
434e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  EmitAlignment(MF->getAlignment(), F);
435e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
436e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  if (MAI->hasDotTypeDotSizeDirective())
437e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    OutStreamer.EmitSymbolAttribute(CurrentFnSym, MCSA_ELF_TypeFunction);
438e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
4397abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  if (isVerbose()) {
440e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    WriteAsOperand(OutStreamer.GetCommentOS(), F,
441e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                   /*PrintType=*/false, F->getParent());
442e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    OutStreamer.GetCommentOS() << '\n';
443e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  }
444e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
445e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  // Emit the CurrentFnSym.  This is a virtual function to allow targets to
446e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  // do their wild and crazy things as required.
447e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  EmitFunctionEntryLabel();
44883d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
4497abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  // If the function had address-taken blocks that got deleted, then we have
4507abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  // references to the dangling symbols.  Emit them at the start of the function
4517abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  // so that we don't get references to undefined symbols.
4527abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  std::vector<MCSymbol*> DeadBlockSyms;
4537abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  MMI->takeDeletedSymbolsForFunction(F, DeadBlockSyms);
4547abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  for (unsigned i = 0, e = DeadBlockSyms.size(); i != e; ++i) {
4557abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    OutStreamer.AddComment("Address taken block that was later removed");
4567abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    OutStreamer.EmitLabel(DeadBlockSyms[i]);
4577abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  }
45883d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
459e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  // Add some workaround for linkonce linkage on Cygwin\MinGW.
460e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  if (MAI->getLinkOnceDirective() != 0 &&
4617abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao      (F->hasLinkOnceLinkage() || F->hasWeakLinkage())) {
462e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    // FIXME: What is this?
46383d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach    MCSymbol *FakeStub =
4647abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao      OutContext.GetOrCreateSymbol(Twine("Lllvm$workaround$fake$stub$")+
4657abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao                                   CurrentFnSym->getName());
4667abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    OutStreamer.EmitLabel(FakeStub);
4677abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  }
46883d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
469e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  // Emit pre-function debug and/or EH information.
470369c4a40cd8c97e1e513ec8c6eaeee26e6adfc9bDaniel Malea#if !defined(ANDROID_TARGET_BUILD) || defined(ANDROID_ENGINEERING_BUILD)
4717abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  if (DE) {
472e2a9508b0f0ac87d802ef01aa8038846c2ef7976Dan Gohman    NamedRegionTimer T(EHTimerName, DWARFGroupName, TimePassesIsEnabled);
473e2a9508b0f0ac87d802ef01aa8038846c2ef7976Dan Gohman    DE->BeginFunction(MF);
4747abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  }
4757abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  if (DD) {
476e2a9508b0f0ac87d802ef01aa8038846c2ef7976Dan Gohman    NamedRegionTimer T(DbgTimerName, DWARFGroupName, TimePassesIsEnabled);
477e2a9508b0f0ac87d802ef01aa8038846c2ef7976Dan Gohman    DD->beginFunction(MF);
4787abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  }
479369c4a40cd8c97e1e513ec8c6eaeee26e6adfc9bDaniel Malea#endif // !ANDROID_TARGET_BUILD || ANDROID_ENGINEERING_BUILD
480e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao}
481e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
482e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao/// EmitFunctionEntryLabel - Emit the label that is the entrypoint for the
483e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao/// function.  This can be overridden by targets as required to do custom stuff.
484e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liaovoid AsmPrinter::EmitFunctionEntryLabel() {
485d095d3410fd7b5f586abcf00b4d990735edef4b7Chris Lattner  // The function label could have already been emitted if two symbols end up
486d095d3410fd7b5f586abcf00b4d990735edef4b7Chris Lattner  // conflicting due to asm renaming.  Detect this and emit an error.
4873e96531186ba574b0c25a4be62d24b8b7d752c9fJim Grosbach  if (CurrentFnSym->isUndefined())
488d095d3410fd7b5f586abcf00b4d990735edef4b7Chris Lattner    return OutStreamer.EmitLabel(CurrentFnSym);
489d095d3410fd7b5f586abcf00b4d990735edef4b7Chris Lattner
490d095d3410fd7b5f586abcf00b4d990735edef4b7Chris Lattner  report_fatal_error("'" + Twine(CurrentFnSym->getName()) +
491d095d3410fd7b5f586abcf00b4d990735edef4b7Chris Lattner                     "' label emitted multiple times to assembly file");
492e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao}
493e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
494c53ade2889c85207e064e4c3d049383ffffb3319Chad Rosier/// emitComments - Pretty-print comments for instructions.
495c53ade2889c85207e064e4c3d049383ffffb3319Chad Rosierstatic void emitComments(const MachineInstr &MI, raw_ostream &CommentOS) {
496abb79d9b00c05bee279441be7e3a12ab12743965Devang Patel  const MachineFunction *MF = MI.getParent()->getParent();
497abb79d9b00c05bee279441be7e3a12ab12743965Devang Patel  const TargetMachine &TM = MF->getTarget();
49883d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
499e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  // Check for spills and reloads
500e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  int FI;
50183d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
502e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  const MachineFrameInfo *FrameInfo = MF->getFrameInfo();
50383d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
504e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  // We assume a single instruction only has a spill or reload, not
505e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  // both.
506e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  const MachineMemOperand *MMO;
507e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  if (TM.getInstrInfo()->isLoadFromStackSlotPostFE(&MI, FI)) {
508e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    if (FrameInfo->isSpillSlotObjectIndex(FI)) {
509e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      MMO = *MI.memoperands_begin();
510e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      CommentOS << MMO->getSize() << "-byte Reload\n";
511e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    }
512e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  } else if (TM.getInstrInfo()->hasLoadFromStackSlot(&MI, MMO, FI)) {
513e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    if (FrameInfo->isSpillSlotObjectIndex(FI))
514e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      CommentOS << MMO->getSize() << "-byte Folded Reload\n";
515e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  } else if (TM.getInstrInfo()->isStoreToStackSlotPostFE(&MI, FI)) {
516e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    if (FrameInfo->isSpillSlotObjectIndex(FI)) {
517e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      MMO = *MI.memoperands_begin();
518e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      CommentOS << MMO->getSize() << "-byte Spill\n";
519e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    }
520e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  } else if (TM.getInstrInfo()->hasStoreToStackSlot(&MI, MMO, FI)) {
521e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    if (FrameInfo->isSpillSlotObjectIndex(FI))
522e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      CommentOS << MMO->getSize() << "-byte Folded Spill\n";
523e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  }
52483d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
525e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  // Check for spill-induced copies
526def3acbff14a29a3295e245b91a639d05f8dc077Jakob Stoklund Olesen  if (MI.getAsmPrinterFlag(MachineInstr::ReloadReuse))
527def3acbff14a29a3295e245b91a639d05f8dc077Jakob Stoklund Olesen    CommentOS << " Reload Reuse\n";
528e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao}
529e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
530c53ade2889c85207e064e4c3d049383ffffb3319Chad Rosier/// emitImplicitDef - This method emits the specified machine instruction
5317abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao/// that is an implicit def.
532c53ade2889c85207e064e4c3d049383ffffb3319Chad Rosierstatic void emitImplicitDef(const MachineInstr *MI, AsmPrinter &AP) {
5337abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  unsigned RegNo = MI->getOperand(0).getReg();
5347abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  AP.OutStreamer.AddComment(Twine("implicit-def: ") +
5357abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao                            AP.TM.getRegisterInfo()->getName(RegNo));
5367abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  AP.OutStreamer.AddBlankLine();
5377abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao}
5387abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao
539c53ade2889c85207e064e4c3d049383ffffb3319Chad Rosierstatic void emitKill(const MachineInstr *MI, AsmPrinter &AP) {
5407abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  std::string Str = "kill:";
5417abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
5427abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    const MachineOperand &Op = MI->getOperand(i);
5437abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    assert(Op.isReg() && "KILL instruction must have only register operands");
5447abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    Str += ' ';
5457abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    Str += AP.TM.getRegisterInfo()->getName(Op.getReg());
5467abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    Str += (Op.isDef() ? "<def>" : "<kill>");
5477abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  }
5487abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  AP.OutStreamer.AddComment(Str);
5497abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  AP.OutStreamer.AddBlankLine();
5507abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao}
5517abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao
552c53ade2889c85207e064e4c3d049383ffffb3319Chad Rosier/// emitDebugValueComment - This method handles the target-independent form
5537abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao/// of DBG_VALUE, returning true if it was able to do so.  A false return
5547abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao/// means the target will need to handle MI in EmitInstruction.
555c53ade2889c85207e064e4c3d049383ffffb3319Chad Rosierstatic bool emitDebugValueComment(const MachineInstr *MI, AsmPrinter &AP) {
5567abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  // This code handles only the 3-operand target-independent form.
5577abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  if (MI->getNumOperands() != 3)
5587abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    return false;
559e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
5607abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  SmallString<128> Str;
5617abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  raw_svector_ostream OS(Str);
5627abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  OS << '\t' << AP.MAI->getCommentString() << "DEBUG_VALUE: ";
5637abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao
5647abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  // cast away const; DIetc do not take const operands for some reason.
5657abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  DIVariable V(const_cast<MDNode*>(MI->getOperand(2).getMetadata()));
56677defb51f91553f5180feef4ae25da44e8d34491Devang Patel  if (V.getContext().isSubprogram())
56719302aa91af26253b5a9d5e39ec5745b0e0cdf66Devang Patel    OS << DISubprogram(V.getContext()).getDisplayName() << ":";
5687abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  OS << V.getName() << " <- ";
5697abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao
5707abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  // Register or immediate value. Register 0 means undef.
5717abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  if (MI->getOperand(0).isFPImm()) {
5727abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    APFloat APF = APFloat(MI->getOperand(0).getFPImm()->getValueAPF());
5737abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    if (MI->getOperand(0).getFPImm()->getType()->isFloatTy()) {
5747abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao      OS << (double)APF.convertToFloat();
5757abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    } else if (MI->getOperand(0).getFPImm()->getType()->isDoubleTy()) {
5767abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao      OS << APF.convertToDouble();
5777abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    } else {
5787abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao      // There is no good way to print long double.  Convert a copy to
5797abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao      // double.  Ah well, it's only a comment.
5807abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao      bool ignored;
5817abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao      APF.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven,
5827abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao                  &ignored);
5837abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao      OS << "(long double) " << APF.convertToDouble();
5847abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    }
5857abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  } else if (MI->getOperand(0).isImm()) {
5867abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    OS << MI->getOperand(0).getImm();
5878594d429e02c688d428036f8563f09572da3fbffDevang Patel  } else if (MI->getOperand(0).isCImm()) {
5888594d429e02c688d428036f8563f09572da3fbffDevang Patel    MI->getOperand(0).getCImm()->getValue().print(OS, false /*isSigned*/);
5897abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  } else {
5907abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    assert(MI->getOperand(0).isReg() && "Unknown operand type");
5917abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    if (MI->getOperand(0).getReg() == 0) {
5927abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao      // Suppress offset, it is not meaningful here.
5937abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao      OS << "undef";
5947abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao      // NOTE: Want this comment at start of line, don't emit with AddComment.
5957abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao      AP.OutStreamer.EmitRawText(OS.str());
5967abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao      return true;
5977abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    }
5987abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    OS << AP.TM.getRegisterInfo()->getName(MI->getOperand(0).getReg());
5997abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  }
60083d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
6017abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  OS << '+' << MI->getOperand(1).getImm();
6027abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  // NOTE: Want this comment at start of line, don't emit with AddComment.
6037abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  AP.OutStreamer.EmitRawText(OS.str());
6047abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  return true;
6057abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao}
606e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
607e29887b4ee42ae78790a8c1886a7babee9ef18e5Rafael EspindolaAsmPrinter::CFIMoveType AsmPrinter::needsCFIMoves() {
608fc2bb8c4448fa884d79e437cc2d2627a7d7740a8Rafael Espindola  if (MAI->getExceptionHandlingType() == ExceptionHandling::DwarfCFI &&
609fc2bb8c4448fa884d79e437cc2d2627a7d7740a8Rafael Espindola      MF->getFunction()->needsUnwindTableEntry())
610fc2bb8c4448fa884d79e437cc2d2627a7d7740a8Rafael Espindola    return CFI_M_EH;
611a432997745f668e85e45826106430f69238b1d1eRafael Espindola
612e29887b4ee42ae78790a8c1886a7babee9ef18e5Rafael Espindola  if (MMI->hasDebugInfo())
613e29887b4ee42ae78790a8c1886a7babee9ef18e5Rafael Espindola    return CFI_M_Debug;
614a432997745f668e85e45826106430f69238b1d1eRafael Espindola
615e29887b4ee42ae78790a8c1886a7babee9ef18e5Rafael Espindola  return CFI_M_None;
616a432997745f668e85e45826106430f69238b1d1eRafael Espindola}
617a432997745f668e85e45826106430f69238b1d1eRafael Espindola
618f46337004ab08076774932785679460ec3d3bb9aCharles Davisbool AsmPrinter::needsSEHMoves() {
619f46337004ab08076774932785679460ec3d3bb9aCharles Davis  return MAI->getExceptionHandlingType() == ExceptionHandling::Win64 &&
620f46337004ab08076774932785679460ec3d3bb9aCharles Davis    MF->getFunction()->needsUnwindTableEntry();
621f46337004ab08076774932785679460ec3d3bb9aCharles Davis}
622f46337004ab08076774932785679460ec3d3bb9aCharles Davis
6232be084a25b1f79f17520d824d0feb8c7854b5f31Nick Lewyckybool AsmPrinter::needsRelocationsForDwarfStringPool() const {
6249cfc799171171e0cc26f64a60ba36bef8e889556Rafael Espindola  return MAI->doesDwarfUseRelocationsAcrossSections();
6252be084a25b1f79f17520d824d0feb8c7854b5f31Nick Lewycky}
6262be084a25b1f79f17520d824d0feb8c7854b5f31Nick Lewycky
627f0adba9a7ec8a3031876575a6ffb7db5f1b6f855Rafael Espindolavoid AsmPrinter::emitPrologLabel(const MachineInstr &MI) {
628f0adba9a7ec8a3031876575a6ffb7db5f1b6f855Rafael Espindola  MCSymbol *Label = MI.getOperand(0).getMCSymbol();
629fea8fea58328d561eeccd5e0f896dbddf17ddb38Rafael Espindola
630f2b04232006142eb7933972fb21d9ffb9b8c2646Rafael Espindola  if (MAI->getExceptionHandlingType() != ExceptionHandling::DwarfCFI)
631f0adba9a7ec8a3031876575a6ffb7db5f1b6f855Rafael Espindola    return;
632f0adba9a7ec8a3031876575a6ffb7db5f1b6f855Rafael Espindola
633e29887b4ee42ae78790a8c1886a7babee9ef18e5Rafael Espindola  if (needsCFIMoves() == CFI_M_None)
634a432997745f668e85e45826106430f69238b1d1eRafael Espindola    return;
635a432997745f668e85e45826106430f69238b1d1eRafael Espindola
636e060a5cd0688caea0e3de670f642f92a4d0b326eBill Wendling  if (MMI->getCompactUnwindEncoding() != 0)
637e060a5cd0688caea0e3de670f642f92a4d0b326eBill Wendling    OutStreamer.EmitCompactUnwindEncoding(MMI->getCompactUnwindEncoding());
638e060a5cd0688caea0e3de670f642f92a4d0b326eBill Wendling
639a432997745f668e85e45826106430f69238b1d1eRafael Espindola  MachineModuleInfo &MMI = MF->getMMI();
640f0adba9a7ec8a3031876575a6ffb7db5f1b6f855Rafael Espindola  std::vector<MachineMove> &Moves = MMI.getFrameMoves();
641b28d4f152ee9b76d8798b2bdcb06cb8d106841e6Rafael Espindola  bool FoundOne = false;
642b28d4f152ee9b76d8798b2bdcb06cb8d106841e6Rafael Espindola  (void)FoundOne;
643f0adba9a7ec8a3031876575a6ffb7db5f1b6f855Rafael Espindola  for (std::vector<MachineMove>::iterator I = Moves.begin(),
644f0adba9a7ec8a3031876575a6ffb7db5f1b6f855Rafael Espindola         E = Moves.end(); I != E; ++I) {
645f0adba9a7ec8a3031876575a6ffb7db5f1b6f855Rafael Espindola    if (I->getLabel() == Label) {
646b28d4f152ee9b76d8798b2bdcb06cb8d106841e6Rafael Espindola      EmitCFIFrameMove(*I);
647b28d4f152ee9b76d8798b2bdcb06cb8d106841e6Rafael Espindola      FoundOne = true;
648f0adba9a7ec8a3031876575a6ffb7db5f1b6f855Rafael Espindola    }
649f0adba9a7ec8a3031876575a6ffb7db5f1b6f855Rafael Espindola  }
650b28d4f152ee9b76d8798b2bdcb06cb8d106841e6Rafael Espindola  assert(FoundOne);
651f0adba9a7ec8a3031876575a6ffb7db5f1b6f855Rafael Espindola}
652f0adba9a7ec8a3031876575a6ffb7db5f1b6f855Rafael Espindola
653e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao/// EmitFunctionBody - This method emits the body and trailer for a
654e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao/// function.
655e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liaovoid AsmPrinter::EmitFunctionBody() {
656e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  // Emit target-specific gunk before the function body.
657e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  EmitFunctionBodyStart();
65883d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
6597abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  bool ShouldPrintDebugScopes = DD && MMI->hasDebugInfo();
66083d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
661e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  // Print out code for the function.
662e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  bool HasAnyRealCode = false;
6635a1bec1ebbe8c4427a31930e6dd6cc81917fc378Bill Wendling  const MachineInstr *LastMI = 0;
664e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  for (MachineFunction::const_iterator I = MF->begin(), E = MF->end();
665e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao       I != E; ++I) {
666e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    // Print a label for the basic block.
667e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    EmitBasicBlockStart(I);
668e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end();
669e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao         II != IE; ++II) {
6705a1bec1ebbe8c4427a31930e6dd6cc81917fc378Bill Wendling      LastMI = II;
6715a1bec1ebbe8c4427a31930e6dd6cc81917fc378Bill Wendling
672e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      // Print the assembly for the instruction.
6731ffdb1f5cb10080ecbcdbeb414ef27a62e53b0f8Dale Johannesen      if (!II->isLabel() && !II->isImplicitDef() && !II->isKill() &&
6741ffdb1f5cb10080ecbcdbeb414ef27a62e53b0f8Dale Johannesen          !II->isDebugValue()) {
675e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao        HasAnyRealCode = true;
676369c4a40cd8c97e1e513ec8c6eaeee26e6adfc9bDaniel Malea
67753a0cbf8e9c52c144b25de5a0d81b5b237c4abbcEvan Cheng        ++EmittedInsts;
678a95f589c757c8c857096a07e0d376ca9aaec6c2cShih-wei Liao      }
679369c4a40cd8c97e1e513ec8c6eaeee26e6adfc9bDaniel Malea#if !defined(ANDROID_TARGET_BUILD) || defined(ANDROID_ENGINEERING_BUILD)
6807abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao      if (ShouldPrintDebugScopes) {
681e2a9508b0f0ac87d802ef01aa8038846c2ef7976Dan Gohman        NamedRegionTimer T(DbgTimerName, DWARFGroupName, TimePassesIsEnabled);
6822bfdc27b1926830b7ab6b6da4d7f02bcd0e8eb2fDevang Patel        DD->beginInstruction(II);
6837abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao      }
684369c4a40cd8c97e1e513ec8c6eaeee26e6adfc9bDaniel Malea#endif // !ANDROID_TARGET_BUILD || ANDROID_ENGINEERING_BUILD
685369c4a40cd8c97e1e513ec8c6eaeee26e6adfc9bDaniel Malea
6867abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao      if (isVerbose())
687c53ade2889c85207e064e4c3d049383ffffb3319Chad Rosier        emitComments(*II, OutStreamer.GetCommentOS());
688e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
689e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      switch (II->getOpcode()) {
690a02effc0bdeef3db3c148485564cab5ab6a7294aBill Wendling      case TargetOpcode::PROLOG_LABEL:
691f0adba9a7ec8a3031876575a6ffb7db5f1b6f855Rafael Espindola        emitPrologLabel(*II);
692f0adba9a7ec8a3031876575a6ffb7db5f1b6f855Rafael Espindola        break;
693f0adba9a7ec8a3031876575a6ffb7db5f1b6f855Rafael Espindola
694e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      case TargetOpcode::EH_LABEL:
695e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      case TargetOpcode::GC_LABEL:
6967abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao        OutStreamer.EmitLabel(II->getOperand(0).getMCSymbol());
697e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao        break;
698e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      case TargetOpcode::INLINEASM:
6997abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao        EmitInlineAsm(II);
7007abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao        break;
7017abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao      case TargetOpcode::DBG_VALUE:
7027abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao        if (isVerbose()) {
703c53ade2889c85207e064e4c3d049383ffffb3319Chad Rosier          if (!emitDebugValueComment(II, *this))
7047abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao            EmitInstruction(II);
7057abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao        }
706e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao        break;
707e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      case TargetOpcode::IMPLICIT_DEF:
708c53ade2889c85207e064e4c3d049383ffffb3319Chad Rosier        if (isVerbose()) emitImplicitDef(II, *this);
709e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao        break;
710e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      case TargetOpcode::KILL:
711c53ade2889c85207e064e4c3d049383ffffb3319Chad Rosier        if (isVerbose()) emitKill(II, *this);
712e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao        break;
713e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      default:
71449a3ff9d1733cb16bdc97590e5b90508b8656565Devang Patel        if (!TM.hasMCUseLoc())
71549a3ff9d1733cb16bdc97590e5b90508b8656565Devang Patel          MCLineEntry::Make(&OutStreamer, getCurrentSection());
71649a3ff9d1733cb16bdc97590e5b90508b8656565Devang Patel
717e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao        EmitInstruction(II);
718e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao        break;
719e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      }
720369c4a40cd8c97e1e513ec8c6eaeee26e6adfc9bDaniel Malea
721369c4a40cd8c97e1e513ec8c6eaeee26e6adfc9bDaniel Malea#if !defined(ANDROID_TARGET_BUILD) || defined(ANDROID_ENGINEERING_BUILD)
7227abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao      if (ShouldPrintDebugScopes) {
723e2a9508b0f0ac87d802ef01aa8038846c2ef7976Dan Gohman        NamedRegionTimer T(DbgTimerName, DWARFGroupName, TimePassesIsEnabled);
7242bfdc27b1926830b7ab6b6da4d7f02bcd0e8eb2fDevang Patel        DD->endInstruction(II);
7257abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao      }
726369c4a40cd8c97e1e513ec8c6eaeee26e6adfc9bDaniel Malea#endif // !ANDROID_TARGET_BUILD || ANDROID_ENGINEERING_BUILD
727e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    }
728e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  }
7295a1bec1ebbe8c4427a31930e6dd6cc81917fc378Bill Wendling
7305a1bec1ebbe8c4427a31930e6dd6cc81917fc378Bill Wendling  // If the last instruction was a prolog label, then we have a situation where
7315a1bec1ebbe8c4427a31930e6dd6cc81917fc378Bill Wendling  // we emitted a prolog but no function body. This results in the ending prolog
7325a1bec1ebbe8c4427a31930e6dd6cc81917fc378Bill Wendling  // label equaling the end of function label and an invalid "row" in the
7335a1bec1ebbe8c4427a31930e6dd6cc81917fc378Bill Wendling  // FDE. We need to emit a noop in this situation so that the FDE's rows are
7345a1bec1ebbe8c4427a31930e6dd6cc81917fc378Bill Wendling  // valid.
735f7e17759079cb76ced7a1c1abf47ade044395c55Bill Wendling  bool RequiresNoop = LastMI && LastMI->isPrologLabel();
7365a1bec1ebbe8c4427a31930e6dd6cc81917fc378Bill Wendling
737e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  // If the function is empty and the object file uses .subsections_via_symbols,
738e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  // then we need to emit *something* to the function body to prevent the
7397abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  // labels from collapsing together.  Just emit a noop.
7405a1bec1ebbe8c4427a31930e6dd6cc81917fc378Bill Wendling  if ((MAI->hasSubsectionsViaSymbols() && !HasAnyRealCode) || RequiresNoop) {
7417abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    MCInst Noop;
7427abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    TM.getInstrInfo()->getNoopForMachoTarget(Noop);
7437abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    if (Noop.getOpcode()) {
7447abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao      OutStreamer.AddComment("avoids zero-length function");
7457abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao      OutStreamer.EmitInstruction(Noop);
7467abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    } else  // Target not mc-ized yet.
7477abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao      OutStreamer.EmitRawText(StringRef("\tnop\n"));
7487abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  }
74983d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
7506c5b2dcd8385e2465f1b9f628d4368fa7c5a3c77Rafael Espindola  const Function *F = MF->getFunction();
7516c5b2dcd8385e2465f1b9f628d4368fa7c5a3c77Rafael Espindola  for (Function::const_iterator i = F->begin(), e = F->end(); i != e; ++i) {
7526c5b2dcd8385e2465f1b9f628d4368fa7c5a3c77Rafael Espindola    const BasicBlock *BB = i;
7536c5b2dcd8385e2465f1b9f628d4368fa7c5a3c77Rafael Espindola    if (!BB->hasAddressTaken())
7546c5b2dcd8385e2465f1b9f628d4368fa7c5a3c77Rafael Espindola      continue;
7556c5b2dcd8385e2465f1b9f628d4368fa7c5a3c77Rafael Espindola    MCSymbol *Sym = GetBlockAddressSymbol(BB);
7566c5b2dcd8385e2465f1b9f628d4368fa7c5a3c77Rafael Espindola    if (Sym->isDefined())
7576c5b2dcd8385e2465f1b9f628d4368fa7c5a3c77Rafael Espindola      continue;
7586c5b2dcd8385e2465f1b9f628d4368fa7c5a3c77Rafael Espindola    OutStreamer.AddComment("Address of block that was removed by CodeGen");
7596c5b2dcd8385e2465f1b9f628d4368fa7c5a3c77Rafael Espindola    OutStreamer.EmitLabel(Sym);
7606c5b2dcd8385e2465f1b9f628d4368fa7c5a3c77Rafael Espindola  }
7616c5b2dcd8385e2465f1b9f628d4368fa7c5a3c77Rafael Espindola
762e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  // Emit target-specific gunk after the function body.
763e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  EmitFunctionBodyEnd();
76483d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
7657abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  // If the target wants a .size directive for the size of the function, emit
7667abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  // it.
7677abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  if (MAI->hasDotTypeDotSizeDirective()) {
7687abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    // Create a symbol for the end of function, so we can get the size as
7697abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    // difference between the function label and the temp label.
7707abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    MCSymbol *FnEndLabel = OutContext.CreateTempSymbol();
7717abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    OutStreamer.EmitLabel(FnEndLabel);
77283d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
7737abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    const MCExpr *SizeExp =
7747abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao      MCBinaryExpr::CreateSub(MCSymbolRefExpr::Create(FnEndLabel, OutContext),
775d55a2664f9493a4c3be242a75d339fac0ebe2e21Hal Finkel                              MCSymbolRefExpr::Create(CurrentFnSymForSize,
776d55a2664f9493a4c3be242a75d339fac0ebe2e21Hal Finkel                                                      OutContext),
7777abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao                              OutContext);
7787abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    OutStreamer.EmitELFSize(CurrentFnSym, SizeExp);
7797abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  }
78083d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
781e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  // Emit post-function debug information.
782369c4a40cd8c97e1e513ec8c6eaeee26e6adfc9bDaniel Malea#if !defined(ANDROID_TARGET_BUILD) || defined(ANDROID_ENGINEERING_BUILD)
7837abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  if (DD) {
784e2a9508b0f0ac87d802ef01aa8038846c2ef7976Dan Gohman    NamedRegionTimer T(DbgTimerName, DWARFGroupName, TimePassesIsEnabled);
785e2a9508b0f0ac87d802ef01aa8038846c2ef7976Dan Gohman    DD->endFunction(MF);
7867abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  }
7877abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  if (DE) {
788e2a9508b0f0ac87d802ef01aa8038846c2ef7976Dan Gohman    NamedRegionTimer T(EHTimerName, DWARFGroupName, TimePassesIsEnabled);
789e2a9508b0f0ac87d802ef01aa8038846c2ef7976Dan Gohman    DE->EndFunction();
7907abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  }
791369c4a40cd8c97e1e513ec8c6eaeee26e6adfc9bDaniel Malea#endif // !ANDROID_TARGET_BUILD || ANDROID_ENGINEERING_BUILD
7927abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  MMI->EndFunction();
79383d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
794e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  // Print out jump tables referenced by the function.
795e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  EmitJumpTableInfo();
79683d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
797e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  OutStreamer.AddBlankLine();
798e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao}
799e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
8007c3efb1a081fdfffdadb7905416577b3a183a6d0Devang Patel/// getDebugValueLocation - Get location information encoded by DBG_VALUE
8017c3efb1a081fdfffdadb7905416577b3a183a6d0Devang Patel/// operands.
80283d808329b81ad7589ddc516566169b0331c25d1Jim GrosbachMachineLocation AsmPrinter::
80383d808329b81ad7589ddc516566169b0331c25d1Jim GrosbachgetDebugValueLocation(const MachineInstr *MI) const {
8047c3efb1a081fdfffdadb7905416577b3a183a6d0Devang Patel  // Target specific DBG_VALUE instructions are handled by each target.
8057c3efb1a081fdfffdadb7905416577b3a183a6d0Devang Patel  return MachineLocation();
8067c3efb1a081fdfffdadb7905416577b3a183a6d0Devang Patel}
807e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
808acc381bee95b5eafcdf3eaa85a66e83a5773aacbDevang Patel/// EmitDwarfRegOp - Emit dwarf register operation.
8090be77dff1147488814b8eea6ec8619f56e3d9f5eDevang Patelvoid AsmPrinter::EmitDwarfRegOp(const MachineLocation &MLoc) const {
810c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel  const TargetRegisterInfo *TRI = TM.getRegisterInfo();
81137afca128db40b086752f3f62464ba08128c3b4dRafael Espindola  int Reg = TRI->getDwarfRegNum(MLoc.getReg(), false);
81237afca128db40b086752f3f62464ba08128c3b4dRafael Espindola
813396618b43a85e12d290a90b181c6af5d7c0c5f11Jakob Stoklund Olesen  for (MCSuperRegIterator SR(MLoc.getReg(), TRI); SR.isValid() && Reg < 0;
814396618b43a85e12d290a90b181c6af5d7c0c5f11Jakob Stoklund Olesen       ++SR) {
81537afca128db40b086752f3f62464ba08128c3b4dRafael Espindola    Reg = TRI->getDwarfRegNum(*SR, false);
81637afca128db40b086752f3f62464ba08128c3b4dRafael Espindola    // FIXME: Get the bit range this register uses of the superregister
81737afca128db40b086752f3f62464ba08128c3b4dRafael Espindola    // so that we can produce a DW_OP_bit_piece
81837afca128db40b086752f3f62464ba08128c3b4dRafael Espindola  }
81937afca128db40b086752f3f62464ba08128c3b4dRafael Espindola
82037afca128db40b086752f3f62464ba08128c3b4dRafael Espindola  // FIXME: Handle cases like a super register being encoded as
82137afca128db40b086752f3f62464ba08128c3b4dRafael Espindola  // DW_OP_reg 32 DW_OP_piece 4 DW_OP_reg 33
82237afca128db40b086752f3f62464ba08128c3b4dRafael Espindola
82337afca128db40b086752f3f62464ba08128c3b4dRafael Espindola  // FIXME: We have no reasonable way of handling errors in here. The
82437afca128db40b086752f3f62464ba08128c3b4dRafael Espindola  // caller might be in the middle of an dwarf expression. We should
82537afca128db40b086752f3f62464ba08128c3b4dRafael Espindola  // probably assert that Reg >= 0 once debug info generation is more mature.
82637afca128db40b086752f3f62464ba08128c3b4dRafael Espindola
827acc381bee95b5eafcdf3eaa85a66e83a5773aacbDevang Patel  if (int Offset =  MLoc.getOffset()) {
828c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel    if (Reg < 32) {
829c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel      OutStreamer.AddComment(
830c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel        dwarf::OperationEncodingString(dwarf::DW_OP_breg0 + Reg));
831c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel      EmitInt8(dwarf::DW_OP_breg0 + Reg);
832c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel    } else {
833c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel      OutStreamer.AddComment("DW_OP_bregx");
834c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel      EmitInt8(dwarf::DW_OP_bregx);
835c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel      OutStreamer.AddComment(Twine(Reg));
836c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel      EmitULEB128(Reg);
837c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel    }
838acc381bee95b5eafcdf3eaa85a66e83a5773aacbDevang Patel    EmitSLEB128(Offset);
839acc381bee95b5eafcdf3eaa85a66e83a5773aacbDevang Patel  } else {
840acc381bee95b5eafcdf3eaa85a66e83a5773aacbDevang Patel    if (Reg < 32) {
841acc381bee95b5eafcdf3eaa85a66e83a5773aacbDevang Patel      OutStreamer.AddComment(
842acc381bee95b5eafcdf3eaa85a66e83a5773aacbDevang Patel        dwarf::OperationEncodingString(dwarf::DW_OP_reg0 + Reg));
843acc381bee95b5eafcdf3eaa85a66e83a5773aacbDevang Patel      EmitInt8(dwarf::DW_OP_reg0 + Reg);
844acc381bee95b5eafcdf3eaa85a66e83a5773aacbDevang Patel    } else {
845c26f5447e39b43a6dd9c1a9d88227f4adf3b5600Devang Patel      OutStreamer.AddComment("DW_OP_regx");
846acc381bee95b5eafcdf3eaa85a66e83a5773aacbDevang Patel      EmitInt8(dwarf::DW_OP_regx);
847acc381bee95b5eafcdf3eaa85a66e83a5773aacbDevang Patel      OutStreamer.AddComment(Twine(Reg));
848acc381bee95b5eafcdf3eaa85a66e83a5773aacbDevang Patel      EmitULEB128(Reg);
849acc381bee95b5eafcdf3eaa85a66e83a5773aacbDevang Patel    }
850acc381bee95b5eafcdf3eaa85a66e83a5773aacbDevang Patel  }
85137afca128db40b086752f3f62464ba08128c3b4dRafael Espindola
85237afca128db40b086752f3f62464ba08128c3b4dRafael Espindola  // FIXME: Produce a DW_OP_bit_piece if we used a superregister
853acc381bee95b5eafcdf3eaa85a66e83a5773aacbDevang Patel}
854acc381bee95b5eafcdf3eaa85a66e83a5773aacbDevang Patel
855e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liaobool AsmPrinter::doFinalization(Module &M) {
856e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  // Emit global variables.
857e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
858e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao       I != E; ++I)
859e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    EmitGlobalVariable(I);
8601ffb5336999b327384752b0f60ad0c4cb4cb8946Rafael Espindola
8611ffb5336999b327384752b0f60ad0c4cb4cb8946Rafael Espindola  // Emit visibility info for declarations
8621ffb5336999b327384752b0f60ad0c4cb4cb8946Rafael Espindola  for (Module::const_iterator I = M.begin(), E = M.end(); I != E; ++I) {
8631ffb5336999b327384752b0f60ad0c4cb4cb8946Rafael Espindola    const Function &F = *I;
8641ffb5336999b327384752b0f60ad0c4cb4cb8946Rafael Espindola    if (!F.isDeclaration())
8651ffb5336999b327384752b0f60ad0c4cb4cb8946Rafael Espindola      continue;
8661ffb5336999b327384752b0f60ad0c4cb4cb8946Rafael Espindola    GlobalValue::VisibilityTypes V = F.getVisibility();
8671ffb5336999b327384752b0f60ad0c4cb4cb8946Rafael Espindola    if (V == GlobalValue::DefaultVisibility)
8681ffb5336999b327384752b0f60ad0c4cb4cb8946Rafael Espindola      continue;
8691ffb5336999b327384752b0f60ad0c4cb4cb8946Rafael Espindola
8701ffb5336999b327384752b0f60ad0c4cb4cb8946Rafael Espindola    MCSymbol *Name = Mang->getSymbol(&F);
8715129bdecd87c518713765acd6998c80f9eef36a2Stuart Hastings    EmitVisibility(Name, V, false);
8721ffb5336999b327384752b0f60ad0c4cb4cb8946Rafael Espindola  }
8731ffb5336999b327384752b0f60ad0c4cb4cb8946Rafael Espindola
874b464d3ff72790260e8c2068afe856fd7299a6834Bill Wendling  // Emit module flags.
875057d521e3d91a894f6c38fcbc21ee5950fbdf7b1Bill Wendling  SmallVector<Module::ModuleFlagEntry, 8> ModuleFlags;
876057d521e3d91a894f6c38fcbc21ee5950fbdf7b1Bill Wendling  M.getModuleFlagsMetadata(ModuleFlags);
877057d521e3d91a894f6c38fcbc21ee5950fbdf7b1Bill Wendling  if (!ModuleFlags.empty())
878057d521e3d91a894f6c38fcbc21ee5950fbdf7b1Bill Wendling    getObjFileLowering().emitModuleFlags(OutStreamer, ModuleFlags, Mang, TM);
879b464d3ff72790260e8c2068afe856fd7299a6834Bill Wendling
8807abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  // Finalize debug and EH information.
881369c4a40cd8c97e1e513ec8c6eaeee26e6adfc9bDaniel Malea#if !defined(ANDROID_TARGET_BUILD) || defined(ANDROID_ENGINEERING_BUILD)
8827abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  if (DE) {
883e2a9508b0f0ac87d802ef01aa8038846c2ef7976Dan Gohman    {
884e2a9508b0f0ac87d802ef01aa8038846c2ef7976Dan Gohman      NamedRegionTimer T(EHTimerName, DWARFGroupName, TimePassesIsEnabled);
8857abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao      DE->EndModule();
8867abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    }
8877abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    delete DE; DE = 0;
8887abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  }
8897abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  if (DD) {
890e2a9508b0f0ac87d802ef01aa8038846c2ef7976Dan Gohman    {
891e2a9508b0f0ac87d802ef01aa8038846c2ef7976Dan Gohman      NamedRegionTimer T(DbgTimerName, DWARFGroupName, TimePassesIsEnabled);
8927abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao      DD->endModule();
8937abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    }
8947abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    delete DD; DD = 0;
8957abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  }
896369c4a40cd8c97e1e513ec8c6eaeee26e6adfc9bDaniel Malea#endif // !ANDROID_TARGET_BUILD || ANDROID_ENGINEERING_BUILD
897369c4a40cd8c97e1e513ec8c6eaeee26e6adfc9bDaniel Malea
898e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  // If the target wants to know about weak references, print them all.
899e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  if (MAI->getWeakRefDirective()) {
900e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    // FIXME: This is not lazy, it would be nice to only print weak references
901e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    // to stuff that is actually used.  Note that doing so would require targets
902e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    // to notice uses in operands (due to constant exprs etc).  This should
903e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    // happen with the MC stuff eventually.
904e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
905e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    // Print out module-level global variables here.
906e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    for (Module::const_global_iterator I = M.global_begin(), E = M.global_end();
907e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao         I != E; ++I) {
908e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      if (!I->hasExternalWeakLinkage()) continue;
9097abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao      OutStreamer.EmitSymbolAttribute(Mang->getSymbol(I), MCSA_WeakReference);
910e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    }
91183d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
912e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    for (Module::const_iterator I = M.begin(), E = M.end(); I != E; ++I) {
913e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      if (!I->hasExternalWeakLinkage()) continue;
9147abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao      OutStreamer.EmitSymbolAttribute(Mang->getSymbol(I), MCSA_WeakReference);
915e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    }
916e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  }
917e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
918e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  if (MAI->hasSetDirective()) {
919e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    OutStreamer.AddBlankLine();
920e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    for (Module::const_alias_iterator I = M.alias_begin(), E = M.alias_end();
921e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao         I != E; ++I) {
9227abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao      MCSymbol *Name = Mang->getSymbol(I);
923e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
924b899d959332871eb62dc22a9ffd81e0e97d96710Jay Foad      const GlobalValue *GV = I->getAliasedGlobal();
9257abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao      MCSymbol *Target = Mang->getSymbol(GV);
926e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
927e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      if (I->hasExternalLinkage() || !MAI->getWeakRefDirective())
928e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao        OutStreamer.EmitSymbolAttribute(Name, MCSA_Global);
929e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      else if (I->hasWeakLinkage())
930e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao        OutStreamer.EmitSymbolAttribute(Name, MCSA_WeakReference);
931e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      else
932e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao        assert(I->hasLocalLinkage() && "Invalid alias linkage");
933e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
934e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      EmitVisibility(Name, I->getVisibility());
935e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
936e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      // Emit the directives as assignments aka .set:
93783d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach      OutStreamer.EmitAssignment(Name,
938e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                                 MCSymbolRefExpr::Create(Target, OutContext));
939e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    }
940e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  }
941e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
942e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  GCModuleInfo *MI = getAnalysisIfAvailable<GCModuleInfo>();
943e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  assert(MI && "AsmPrinter didn't require GCModuleInfo?");
944e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  for (GCModuleInfo::iterator I = MI->end(), E = MI->begin(); I != E; )
945e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    if (GCMetadataPrinter *MP = GetOrCreateGCPrinter(*--I))
9467abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao      MP->finishAssembly(*this);
947e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
948e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  // If we don't have any trampolines, then we don't require stack memory
949e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  // to be executable. Some targets have a directive to declare this.
950e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  Function *InitTrampolineIntrinsic = M.getFunction("llvm.init.trampoline");
951e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  if (!InitTrampolineIntrinsic || InitTrampolineIntrinsic->use_empty())
9527abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    if (const MCSection *S = MAI->getNonexecutableStackSection(OutContext))
953e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      OutStreamer.SwitchSection(S);
95483d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
955e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  // Allow the target to emit any magic that it wants at the end of the file,
956e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  // after everything else has gone out.
957e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  EmitEndOfAsmFile(M);
95883d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
959e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  delete Mang; Mang = 0;
9607abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  MMI = 0;
96183d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
962e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  OutStreamer.Finish();
963e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  return false;
964e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao}
965e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
966e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liaovoid AsmPrinter::SetupMachineFunction(MachineFunction &MF) {
967e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  this->MF = &MF;
968e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  // Get the function symbol.
9697abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  CurrentFnSym = Mang->getSymbol(MF.getFunction());
970d55a2664f9493a4c3be242a75d339fac0ebe2e21Hal Finkel  CurrentFnSymForSize = CurrentFnSym;
971e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
9727abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  if (isVerbose())
973e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    LI = &getAnalysis<MachineLoopInfo>();
974e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao}
975e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
976e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liaonamespace {
977e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  // SectionCPs - Keep track the alignment, constpool entries per Section.
978e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  struct SectionCPs {
979e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    const MCSection *S;
980e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    unsigned Alignment;
981e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    SmallVector<unsigned, 4> CPEs;
982e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    SectionCPs(const MCSection *s, unsigned a) : S(s), Alignment(a) {}
983e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  };
984e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao}
985e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
986e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao/// EmitConstantPool - Print to the current output stream assembly
987e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao/// representations of the constants in the constant pool MCP. This is
988e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao/// used to print out constants which have been "spilled to memory" by
989e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao/// the code generator.
990e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao///
991e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liaovoid AsmPrinter::EmitConstantPool() {
992e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  const MachineConstantPool *MCP = MF->getConstantPool();
993e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  const std::vector<MachineConstantPoolEntry> &CP = MCP->getConstants();
994e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  if (CP.empty()) return;
995e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
996e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  // Calculate sections for constant pool entries. We collect entries to go into
997e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  // the same section together to reduce amount of section switch statements.
998e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  SmallVector<SectionCPs, 4> CPSections;
999e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  for (unsigned i = 0, e = CP.size(); i != e; ++i) {
1000e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    const MachineConstantPoolEntry &CPE = CP[i];
1001e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    unsigned Align = CPE.getAlignment();
100283d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
1003e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    SectionKind Kind;
1004e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    switch (CPE.getRelocationInfo()) {
1005e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    default: llvm_unreachable("Unknown section kind");
1006e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    case 2: Kind = SectionKind::getReadOnlyWithRel(); break;
1007e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    case 1:
1008e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      Kind = SectionKind::getReadOnlyWithRelLocal();
1009e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      break;
1010e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    case 0:
1011e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    switch (TM.getTargetData()->getTypeAllocSize(CPE.getType())) {
1012e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    case 4:  Kind = SectionKind::getMergeableConst4(); break;
1013e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    case 8:  Kind = SectionKind::getMergeableConst8(); break;
1014e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    case 16: Kind = SectionKind::getMergeableConst16();break;
1015e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    default: Kind = SectionKind::getMergeableConst(); break;
1016e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    }
1017e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    }
1018e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
1019e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    const MCSection *S = getObjFileLowering().getSectionForConstant(Kind);
102083d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
1021e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    // The number of sections are small, just do a linear search from the
1022e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    // last section to the first.
1023e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    bool Found = false;
1024e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    unsigned SecIdx = CPSections.size();
1025e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    while (SecIdx != 0) {
1026e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      if (CPSections[--SecIdx].S == S) {
1027e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao        Found = true;
1028e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao        break;
1029e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      }
1030e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    }
1031e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    if (!Found) {
1032e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      SecIdx = CPSections.size();
1033e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      CPSections.push_back(SectionCPs(S, Align));
1034e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    }
1035e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
1036e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    if (Align > CPSections[SecIdx].Alignment)
1037e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      CPSections[SecIdx].Alignment = Align;
1038e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    CPSections[SecIdx].CPEs.push_back(i);
1039e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  }
1040e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
1041e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  // Now print stuff into the calculated sections.
1042e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  for (unsigned i = 0, e = CPSections.size(); i != e; ++i) {
1043e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    OutStreamer.SwitchSection(CPSections[i].S);
1044e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    EmitAlignment(Log2_32(CPSections[i].Alignment));
1045e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
1046e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    unsigned Offset = 0;
1047e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    for (unsigned j = 0, ee = CPSections[i].CPEs.size(); j != ee; ++j) {
1048e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      unsigned CPI = CPSections[i].CPEs[j];
1049e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      MachineConstantPoolEntry CPE = CP[CPI];
1050e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
1051e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      // Emit inter-object padding for alignment.
1052e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      unsigned AlignMask = CPE.getAlignment() - 1;
1053e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      unsigned NewOffset = (Offset + AlignMask) & ~AlignMask;
1054e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      OutStreamer.EmitFill(NewOffset - Offset, 0/*fillval*/, 0/*addrspace*/);
1055e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
1056db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner      Type *Ty = CPE.getType();
1057e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      Offset = NewOffset + TM.getTargetData()->getTypeAllocSize(Ty);
1058e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      OutStreamer.EmitLabel(GetCPISymbol(CPI));
1059e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
1060e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      if (CPE.isMachineConstantPoolEntry())
1061e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao        EmitMachineConstantPoolValue(CPE.Val.MachineCPVal);
1062e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      else
1063e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao        EmitGlobalConstant(CPE.Val.ConstVal);
1064e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    }
1065e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  }
1066e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao}
1067e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
1068e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao/// EmitJumpTableInfo - Print assembly representations of the jump tables used
106983d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach/// by the current function to the current output stream.
1070e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao///
1071e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liaovoid AsmPrinter::EmitJumpTableInfo() {
1072e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  const MachineJumpTableInfo *MJTI = MF->getJumpTableInfo();
1073e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  if (MJTI == 0) return;
10747abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  if (MJTI->getEntryKind() == MachineJumpTableInfo::EK_Inline) return;
1075e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  const std::vector<MachineJumpTableEntry> &JT = MJTI->getJumpTables();
1076e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  if (JT.empty()) return;
1077e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
107883d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach  // Pick the directive to use to print the jump table entries, and switch to
1079e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  // the appropriate section.
1080e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  const Function *F = MF->getFunction();
1081e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  bool JTInDiffSection = false;
1082e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  if (// In PIC mode, we need to emit the jump table to the same section as the
1083e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      // function body itself, otherwise the label differences won't make sense.
1084e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      // FIXME: Need a better predicate for this: what about custom entries?
1085e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      MJTI->getEntryKind() == MachineJumpTableInfo::EK_LabelDifference32 ||
1086e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      // We should also do if the section name is NULL or function is declared
1087e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      // in discardable section
1088e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      // FIXME: this isn't the right predicate, should be based on the MCSection
1089e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      // for the function.
1090e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      F->isWeakForLinker()) {
1091e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    OutStreamer.SwitchSection(getObjFileLowering().SectionForGlobal(F,Mang,TM));
1092e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  } else {
1093e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    // Otherwise, drop it in the readonly section.
109483d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach    const MCSection *ReadOnlySection =
1095e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      getObjFileLowering().getSectionForConstant(SectionKind::getReadOnly());
1096e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    OutStreamer.SwitchSection(ReadOnlySection);
1097e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    JTInDiffSection = true;
1098e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  }
1099e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
1100e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  EmitAlignment(Log2_32(MJTI->getEntryAlignment(*TM.getTargetData())));
110183d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
1102e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  for (unsigned JTI = 0, e = JT.size(); JTI != e; ++JTI) {
1103e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    const std::vector<MachineBasicBlock*> &JTBBs = JT[JTI].MBBs;
110483d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
110583d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach    // If this jump table was deleted, ignore it.
1106e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    if (JTBBs.empty()) continue;
1107e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
1108e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    // For the EK_LabelDifference32 entry, if the target supports .set, emit a
1109e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    // .set directive for each unique entry.  This reduces the number of
1110e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    // relocations the assembler will generate for the jump table.
1111e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    if (MJTI->getEntryKind() == MachineJumpTableInfo::EK_LabelDifference32 &&
1112e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao        MAI->hasSetDirective()) {
1113e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      SmallPtrSet<const MachineBasicBlock*, 16> EmittedSets;
1114e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      const TargetLowering *TLI = TM.getTargetLowering();
1115e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      const MCExpr *Base = TLI->getPICJumpTableRelocBaseExpr(MF,JTI,OutContext);
1116e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      for (unsigned ii = 0, ee = JTBBs.size(); ii != ee; ++ii) {
1117e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao        const MachineBasicBlock *MBB = JTBBs[ii];
1118e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao        if (!EmittedSets.insert(MBB)) continue;
111983d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
1120e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao        // .set LJTSet, LBB32-base
1121e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao        const MCExpr *LHS =
11227abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao          MCSymbolRefExpr::Create(MBB->getSymbol(), OutContext);
1123e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao        OutStreamer.EmitAssignment(GetJTSetSymbol(JTI, MBB->getNumber()),
1124e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                                MCBinaryExpr::CreateSub(LHS, Base, OutContext));
1125e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      }
112683d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach    }
112783d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
1128ab4c366274a582dd8146b2820c6b999cad5fce36Duncan Sands    // On some targets (e.g. Darwin) we want to emit two consecutive labels
1129e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    // before each jump table.  The first label is never referenced, but tells
1130e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    // the assembler and linker the extents of the jump table object.  The
1131e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    // second label is actually referenced by the code.
1132e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    if (JTInDiffSection && MAI->getLinkerPrivateGlobalPrefix()[0])
1133e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      // FIXME: This doesn't have to have any specific name, just any randomly
1134e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      // named and numbered 'l' label would work.  Simplify GetJTISymbol.
1135e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      OutStreamer.EmitLabel(GetJTISymbol(JTI, true));
1136e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
1137e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    OutStreamer.EmitLabel(GetJTISymbol(JTI));
1138e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
1139e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    for (unsigned ii = 0, ee = JTBBs.size(); ii != ee; ++ii)
1140e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      EmitJumpTableEntry(MJTI, JTBBs[ii], JTI);
1141e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  }
1142e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao}
1143e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
1144e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao/// EmitJumpTableEntry - Emit a jump table entry for the specified MBB to the
1145e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao/// current stream.
1146e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liaovoid AsmPrinter::EmitJumpTableEntry(const MachineJumpTableInfo *MJTI,
1147e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                                    const MachineBasicBlock *MBB,
1148e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                                    unsigned UID) const {
1149e5005d0062fa4c8f5707428f7b8ad8484a002d83Jakob Stoklund Olesen  assert(MBB && MBB->getNumber() >= 0 && "Invalid basic block");
1150e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  const MCExpr *Value = 0;
1151e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  switch (MJTI->getEntryKind()) {
11527abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  case MachineJumpTableInfo::EK_Inline:
11534d6ccb5f68cd7c6418a209f1fa4dbade569e4493David Blaikie    llvm_unreachable("Cannot emit EK_Inline jump table entry");
1154e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  case MachineJumpTableInfo::EK_Custom32:
1155e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    Value = TM.getTargetLowering()->LowerCustomJumpTableEntry(MJTI, MBB, UID,
1156e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                                                              OutContext);
1157e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    break;
1158e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  case MachineJumpTableInfo::EK_BlockAddress:
1159e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    // EK_BlockAddress - Each entry is a plain address of block, e.g.:
1160e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    //     .word LBB123
11617abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    Value = MCSymbolRefExpr::Create(MBB->getSymbol(), OutContext);
1162e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    break;
1163e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  case MachineJumpTableInfo::EK_GPRel32BlockAddress: {
1164e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    // EK_GPRel32BlockAddress - Each entry is an address of block, encoded
1165e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    // with a relocation as gp-relative, e.g.:
1166e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    //     .gprel32 LBB123
11677abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    MCSymbol *MBBSym = MBB->getSymbol();
1168e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    OutStreamer.EmitGPRel32Value(MCSymbolRefExpr::Create(MBBSym, OutContext));
1169e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    return;
1170e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  }
1171e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
11726c2cf8b1fbcf70fd9db6fe44032c1ceaa2299760Akira Hatanaka  case MachineJumpTableInfo::EK_GPRel64BlockAddress: {
11736c2cf8b1fbcf70fd9db6fe44032c1ceaa2299760Akira Hatanaka    // EK_GPRel64BlockAddress - Each entry is an address of block, encoded
11746c2cf8b1fbcf70fd9db6fe44032c1ceaa2299760Akira Hatanaka    // with a relocation as gp-relative, e.g.:
11756c2cf8b1fbcf70fd9db6fe44032c1ceaa2299760Akira Hatanaka    //     .gpdword LBB123
11766c2cf8b1fbcf70fd9db6fe44032c1ceaa2299760Akira Hatanaka    MCSymbol *MBBSym = MBB->getSymbol();
11776c2cf8b1fbcf70fd9db6fe44032c1ceaa2299760Akira Hatanaka    OutStreamer.EmitGPRel64Value(MCSymbolRefExpr::Create(MBBSym, OutContext));
11786c2cf8b1fbcf70fd9db6fe44032c1ceaa2299760Akira Hatanaka    return;
11796c2cf8b1fbcf70fd9db6fe44032c1ceaa2299760Akira Hatanaka  }
11806c2cf8b1fbcf70fd9db6fe44032c1ceaa2299760Akira Hatanaka
1181e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  case MachineJumpTableInfo::EK_LabelDifference32: {
1182e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    // EK_LabelDifference32 - Each entry is the address of the block minus
1183e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    // the address of the jump table.  This is used for PIC jump tables where
1184e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    // gprel32 is not supported.  e.g.:
1185e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    //      .word LBB123 - LJTI1_2
1186e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    // If the .set directive is supported, this is emitted as:
1187e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    //      .set L4_5_set_123, LBB123 - LJTI1_2
1188e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    //      .word L4_5_set_123
118983d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
119083d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach    // If we have emitted set directives for the jump table entries, print
1191e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    // them rather than the entries themselves.  If we're emitting PIC, then
1192e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    // emit the table entries as differences between two text section labels.
1193e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    if (MAI->hasSetDirective()) {
1194e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      // If we used .set, reference the .set's symbol.
1195e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      Value = MCSymbolRefExpr::Create(GetJTSetSymbol(UID, MBB->getNumber()),
1196e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                                      OutContext);
1197e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      break;
1198e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    }
1199e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    // Otherwise, use the difference as the jump table entry.
12007abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    Value = MCSymbolRefExpr::Create(MBB->getSymbol(), OutContext);
1201e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    const MCExpr *JTI = MCSymbolRefExpr::Create(GetJTISymbol(UID), OutContext);
1202e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    Value = MCBinaryExpr::CreateSub(Value, JTI, OutContext);
1203e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    break;
1204e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  }
1205e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  }
120683d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
1207e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  assert(Value && "Unknown entry kind!");
120883d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
1209e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  unsigned EntrySize = MJTI->getEntrySize(*TM.getTargetData());
1210e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  OutStreamer.EmitValue(Value, EntrySize, /*addrspace*/0);
1211e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao}
1212e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
1213e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
1214e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao/// EmitSpecialLLVMGlobal - Check to see if the specified global is a
1215e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao/// special global used by LLVM.  If so, emit it and return true, otherwise
1216e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao/// do nothing and return false.
1217e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liaobool AsmPrinter::EmitSpecialLLVMGlobal(const GlobalVariable *GV) {
1218e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  if (GV->getName() == "llvm.used") {
1219e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    if (MAI->hasNoDeadStrip())    // No need to emit this at all.
1220e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      EmitLLVMUsedList(GV->getInitializer());
1221e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    return true;
1222e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  }
1223e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
1224e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  // Ignore debug and non-emitted data.  This handles llvm.compiler.used.
1225e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  if (GV->getSection() == "llvm.metadata" ||
1226e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      GV->hasAvailableExternallyLinkage())
1227e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    return true;
122883d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
1229e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  if (!GV->hasAppendingLinkage()) return false;
1230e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
1231e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  assert(GV->hasInitializer() && "Not a special LLVM global!");
123283d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
1233e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  if (GV->getName() == "llvm.global_ctors") {
12344a99f59aef358fb93eac180e49f6dcef03822046Anton Korobeynikov    EmitXXStructorList(GV->getInitializer(), /* isCtor */ true);
123583d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
1236e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    if (TM.getRelocationModel() == Reloc::Static &&
1237e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao        MAI->hasStaticCtorDtorReferenceInStaticMode()) {
1238e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      StringRef Sym(".constructors_used");
1239e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      OutStreamer.EmitSymbolAttribute(OutContext.GetOrCreateSymbol(Sym),
1240e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                                      MCSA_Reference);
1241e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    }
1242e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    return true;
124383d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach  }
124483d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
1245e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  if (GV->getName() == "llvm.global_dtors") {
12464a99f59aef358fb93eac180e49f6dcef03822046Anton Korobeynikov    EmitXXStructorList(GV->getInitializer(), /* isCtor */ false);
1247e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
1248e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    if (TM.getRelocationModel() == Reloc::Static &&
1249e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao        MAI->hasStaticCtorDtorReferenceInStaticMode()) {
1250e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      StringRef Sym(".destructors_used");
1251e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      OutStreamer.EmitSymbolAttribute(OutContext.GetOrCreateSymbol(Sym),
1252e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                                      MCSA_Reference);
1253e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    }
1254e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    return true;
1255e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  }
125683d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
1257e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  return false;
1258e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao}
1259e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
1260e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao/// EmitLLVMUsedList - For targets that define a MAI::UsedDirective, mark each
1261e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao/// global in the specified llvm.used list for which emitUsedDirectiveFor
1262e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao/// is true, as being used with this directive.
12637d715dfe6d66be257926f626df96a0e2bd38dc1fJay Foadvoid AsmPrinter::EmitLLVMUsedList(const Constant *List) {
1264e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  // Should be an array of 'i8*'.
12657d715dfe6d66be257926f626df96a0e2bd38dc1fJay Foad  const ConstantArray *InitList = dyn_cast<ConstantArray>(List);
1266e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  if (InitList == 0) return;
126783d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
1268e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) {
1269e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    const GlobalValue *GV =
1270e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      dyn_cast<GlobalValue>(InitList->getOperand(i)->stripPointerCasts());
1271e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    if (GV && getObjFileLowering().shouldEmitUsedDirectiveFor(GV, Mang))
12727abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao      OutStreamer.EmitSymbolAttribute(Mang->getSymbol(GV), MCSA_NoDeadStrip);
1273e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  }
1274e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao}
1275e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
12764a99f59aef358fb93eac180e49f6dcef03822046Anton Korobeynikovtypedef std::pair<unsigned, Constant*> Structor;
1277fd9c4f76f4a1ec06891a3405198fc907f8253958Duncan Sands
12789a7d48ae67d1f151d5339d37ce66c57179de77b4Duncan Sandsstatic bool priority_order(const Structor& lhs, const Structor& rhs) {
1279fd9c4f76f4a1ec06891a3405198fc907f8253958Duncan Sands  return lhs.first < rhs.first;
1280fd9c4f76f4a1ec06891a3405198fc907f8253958Duncan Sands}
1281fd9c4f76f4a1ec06891a3405198fc907f8253958Duncan Sands
1282fd9c4f76f4a1ec06891a3405198fc907f8253958Duncan Sands/// EmitXXStructorList - Emit the ctor or dtor list taking into account the init
1283fd9c4f76f4a1ec06891a3405198fc907f8253958Duncan Sands/// priority.
12844a99f59aef358fb93eac180e49f6dcef03822046Anton Korobeynikovvoid AsmPrinter::EmitXXStructorList(const Constant *List, bool isCtor) {
1285e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  // Should be an array of '{ int, void ()* }' structs.  The first value is the
1286fd9c4f76f4a1ec06891a3405198fc907f8253958Duncan Sands  // init priority.
1287e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  if (!isa<ConstantArray>(List)) return;
1288fd9c4f76f4a1ec06891a3405198fc907f8253958Duncan Sands
1289fd9c4f76f4a1ec06891a3405198fc907f8253958Duncan Sands  // Sanity check the structors list.
1290fd9c4f76f4a1ec06891a3405198fc907f8253958Duncan Sands  const ConstantArray *InitList = dyn_cast<ConstantArray>(List);
1291fd9c4f76f4a1ec06891a3405198fc907f8253958Duncan Sands  if (!InitList) return; // Not an array!
1292fd9c4f76f4a1ec06891a3405198fc907f8253958Duncan Sands  StructType *ETy = dyn_cast<StructType>(InitList->getType()->getElementType());
1293fd9c4f76f4a1ec06891a3405198fc907f8253958Duncan Sands  if (!ETy || ETy->getNumElements() != 2) return; // Not an array of pairs!
1294fd9c4f76f4a1ec06891a3405198fc907f8253958Duncan Sands  if (!isa<IntegerType>(ETy->getTypeAtIndex(0U)) ||
1295fd9c4f76f4a1ec06891a3405198fc907f8253958Duncan Sands      !isa<PointerType>(ETy->getTypeAtIndex(1U))) return; // Not (int, ptr).
1296fd9c4f76f4a1ec06891a3405198fc907f8253958Duncan Sands
1297fd9c4f76f4a1ec06891a3405198fc907f8253958Duncan Sands  // Gather the structors in a form that's convenient for sorting by priority.
1298fd9c4f76f4a1ec06891a3405198fc907f8253958Duncan Sands  SmallVector<Structor, 8> Structors;
1299fd9c4f76f4a1ec06891a3405198fc907f8253958Duncan Sands  for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) {
1300fd9c4f76f4a1ec06891a3405198fc907f8253958Duncan Sands    ConstantStruct *CS = dyn_cast<ConstantStruct>(InitList->getOperand(i));
1301fd9c4f76f4a1ec06891a3405198fc907f8253958Duncan Sands    if (!CS) continue; // Malformed.
1302fd9c4f76f4a1ec06891a3405198fc907f8253958Duncan Sands    if (CS->getOperand(1)->isNullValue())
1303fd9c4f76f4a1ec06891a3405198fc907f8253958Duncan Sands      break;  // Found a null terminator, skip the rest.
1304fd9c4f76f4a1ec06891a3405198fc907f8253958Duncan Sands    ConstantInt *Priority = dyn_cast<ConstantInt>(CS->getOperand(0));
1305fd9c4f76f4a1ec06891a3405198fc907f8253958Duncan Sands    if (!Priority) continue; // Malformed.
1306fd9c4f76f4a1ec06891a3405198fc907f8253958Duncan Sands    Structors.push_back(std::make_pair(Priority->getLimitedValue(65535),
1307fd9c4f76f4a1ec06891a3405198fc907f8253958Duncan Sands                                       CS->getOperand(1)));
1308fd9c4f76f4a1ec06891a3405198fc907f8253958Duncan Sands  }
1309fd9c4f76f4a1ec06891a3405198fc907f8253958Duncan Sands
13104a99f59aef358fb93eac180e49f6dcef03822046Anton Korobeynikov  // Emit the function pointers in the target-specific order
13114a99f59aef358fb93eac180e49f6dcef03822046Anton Korobeynikov  const TargetData *TD = TM.getTargetData();
13124a99f59aef358fb93eac180e49f6dcef03822046Anton Korobeynikov  unsigned Align = Log2_32(TD->getPointerPrefAlignment());
13134a99f59aef358fb93eac180e49f6dcef03822046Anton Korobeynikov  std::stable_sort(Structors.begin(), Structors.end(), priority_order);
13144a99f59aef358fb93eac180e49f6dcef03822046Anton Korobeynikov  for (unsigned i = 0, e = Structors.size(); i != e; ++i) {
13154a99f59aef358fb93eac180e49f6dcef03822046Anton Korobeynikov    const MCSection *OutputSection =
13164a99f59aef358fb93eac180e49f6dcef03822046Anton Korobeynikov      (isCtor ?
13174a99f59aef358fb93eac180e49f6dcef03822046Anton Korobeynikov       getObjFileLowering().getStaticCtorSection(Structors[i].first) :
13184a99f59aef358fb93eac180e49f6dcef03822046Anton Korobeynikov       getObjFileLowering().getStaticDtorSection(Structors[i].first));
13194a99f59aef358fb93eac180e49f6dcef03822046Anton Korobeynikov    OutStreamer.SwitchSection(OutputSection);
13204a99f59aef358fb93eac180e49f6dcef03822046Anton Korobeynikov    if (OutStreamer.getCurrentSection() != OutStreamer.getPreviousSection())
13214a99f59aef358fb93eac180e49f6dcef03822046Anton Korobeynikov      EmitAlignment(Align);
132234982576a43887e7f062ed0a3571af2cbab003f3James Molloy    EmitXXStructor(Structors[i].second);
1323147272b8a70db7984a6bdfad3b5efabcb794a42eDuncan Sands  }
1324e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao}
1325e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
1326e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao//===--------------------------------------------------------------------===//
1327e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao// Emission and print routines
1328e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao//
1329e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
1330e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao/// EmitInt8 - Emit a byte directive and value.
1331e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao///
1332e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liaovoid AsmPrinter::EmitInt8(int Value) const {
1333e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  OutStreamer.EmitIntValue(Value, 1, 0/*addrspace*/);
1334e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao}
1335e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
1336e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao/// EmitInt16 - Emit a short directive and value.
1337e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao///
1338e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liaovoid AsmPrinter::EmitInt16(int Value) const {
1339e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  OutStreamer.EmitIntValue(Value, 2, 0/*addrspace*/);
1340e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao}
1341e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
1342e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao/// EmitInt32 - Emit a long directive and value.
1343e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao///
1344e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liaovoid AsmPrinter::EmitInt32(int Value) const {
1345e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  OutStreamer.EmitIntValue(Value, 4, 0/*addrspace*/);
1346e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao}
1347e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
13487abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao/// EmitLabelDifference - Emit something like ".long Hi-Lo" where the size
13497abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao/// in bytes of the directive is specified by Size and Hi/Lo specify the
13507abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao/// labels.  This implicitly uses .set if it is available.
13517abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liaovoid AsmPrinter::EmitLabelDifference(const MCSymbol *Hi, const MCSymbol *Lo,
13527abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao                                     unsigned Size) const {
13537abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  // Get the Hi-Lo expression.
135483d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach  const MCExpr *Diff =
13557abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    MCBinaryExpr::CreateSub(MCSymbolRefExpr::Create(Hi, OutContext),
13567abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao                            MCSymbolRefExpr::Create(Lo, OutContext),
13577abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao                            OutContext);
135883d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
13597abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  if (!MAI->hasSetDirective()) {
13607abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    OutStreamer.EmitValue(Diff, Size, 0/*AddrSpace*/);
13617abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    return;
13627abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  }
13637abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao
13647abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  // Otherwise, emit with .set (aka assignment).
13657abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  MCSymbol *SetLabel = GetTempSymbol("set", SetCounter++);
13667abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  OutStreamer.EmitAssignment(SetLabel, Diff);
13677abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  OutStreamer.EmitSymbolValue(SetLabel, Size, 0/*AddrSpace*/);
13687abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao}
13697abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao
137083d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach/// EmitLabelOffsetDifference - Emit something like ".long Hi+Offset-Lo"
13717abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao/// where the size in bytes of the directive is specified by Size and Hi/Lo
13727abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao/// specify the labels.  This implicitly uses .set if it is available.
13737abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liaovoid AsmPrinter::EmitLabelOffsetDifference(const MCSymbol *Hi, uint64_t Offset,
137483d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach                                           const MCSymbol *Lo, unsigned Size)
13757abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  const {
137683d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
13777abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  // Emit Hi+Offset - Lo
13787abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  // Get the Hi+Offset expression.
13797abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  const MCExpr *Plus =
138083d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach    MCBinaryExpr::CreateAdd(MCSymbolRefExpr::Create(Hi, OutContext),
13817abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao                            MCConstantExpr::Create(Offset, OutContext),
13827abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao                            OutContext);
138383d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
13847abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  // Get the Hi+Offset-Lo expression.
138583d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach  const MCExpr *Diff =
13867abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    MCBinaryExpr::CreateSub(Plus,
13877abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao                            MCSymbolRefExpr::Create(Lo, OutContext),
13887abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao                            OutContext);
138983d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
139083d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach  if (!MAI->hasSetDirective())
13917abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    OutStreamer.EmitValue(Diff, 4, 0/*AddrSpace*/);
13927abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  else {
13937abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    // Otherwise, emit with .set (aka assignment).
13947abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    MCSymbol *SetLabel = GetTempSymbol("set", SetCounter++);
13957abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    OutStreamer.EmitAssignment(SetLabel, Diff);
13967abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    OutStreamer.EmitSymbolValue(SetLabel, 4, 0/*AddrSpace*/);
13977abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  }
1398e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao}
139917e9a62a01856bfe87c5cadacdf03b9d51397b56Devang Patel
140083d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach/// EmitLabelPlusOffset - Emit something like ".long Label+Offset"
140117e9a62a01856bfe87c5cadacdf03b9d51397b56Devang Patel/// where the size in bytes of the directive is specified by Size and Label
140217e9a62a01856bfe87c5cadacdf03b9d51397b56Devang Patel/// specifies the label.  This implicitly uses .set if it is available.
140317e9a62a01856bfe87c5cadacdf03b9d51397b56Devang Patelvoid AsmPrinter::EmitLabelPlusOffset(const MCSymbol *Label, uint64_t Offset,
140483d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach                                      unsigned Size)
140517e9a62a01856bfe87c5cadacdf03b9d51397b56Devang Patel  const {
140683d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
1407ffccd923101ae177c1a2c407618d8f03a312d69bNick Lewycky  // Emit Label+Offset (or just Label if Offset is zero)
1408ffccd923101ae177c1a2c407618d8f03a312d69bNick Lewycky  const MCExpr *Expr = MCSymbolRefExpr::Create(Label, OutContext);
1409ffccd923101ae177c1a2c407618d8f03a312d69bNick Lewycky  if (Offset)
1410ffccd923101ae177c1a2c407618d8f03a312d69bNick Lewycky    Expr = MCBinaryExpr::CreateAdd(Expr,
1411ffccd923101ae177c1a2c407618d8f03a312d69bNick Lewycky                                   MCConstantExpr::Create(Offset, OutContext),
1412ffccd923101ae177c1a2c407618d8f03a312d69bNick Lewycky                                   OutContext);
141383d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
1414ffccd923101ae177c1a2c407618d8f03a312d69bNick Lewycky  OutStreamer.EmitValue(Expr, Size, 0/*AddrSpace*/);
141517e9a62a01856bfe87c5cadacdf03b9d51397b56Devang Patel}
141683d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
1417e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
1418e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao//===----------------------------------------------------------------------===//
1419e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
1420e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao// EmitAlignment - Emit an alignment directive to the specified power of
1421e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao// two boundary.  For example, if you pass in 3 here, you will get an 8
1422e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao// byte alignment.  If a global value is specified, and if that global has
14237516e9ec8193626b3bc987ea7eec3ec2e89e0f9eChris Lattner// an explicit alignment requested, it will override the alignment request
14247516e9ec8193626b3bc987ea7eec3ec2e89e0f9eChris Lattner// if required for correctness.
1425e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao//
1426027b93645e161c2c511ea19f2c3c417870eeade5Chris Lattnervoid AsmPrinter::EmitAlignment(unsigned NumBits, const GlobalValue *GV) const {
14277516e9ec8193626b3bc987ea7eec3ec2e89e0f9eChris Lattner  if (GV) NumBits = getGVAlignmentLog2(GV, *TM.getTargetData(), NumBits);
142883d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
14297516e9ec8193626b3bc987ea7eec3ec2e89e0f9eChris Lattner  if (NumBits == 0) return;   // 1-byte aligned: no need to emit alignment.
143083d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
1431e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  if (getCurrentSection()->getKind().isText())
1432e4454320b3cfffe926a487c33fbeb454366de2f8Shih-wei Liao    OutStreamer.EmitCodeAlignment(1 << NumBits);
1433e4454320b3cfffe926a487c33fbeb454366de2f8Shih-wei Liao  else
1434e4454320b3cfffe926a487c33fbeb454366de2f8Shih-wei Liao    OutStreamer.EmitValueToAlignment(1 << NumBits, 0, 1, 0);
1435e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao}
1436e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
14377abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao//===----------------------------------------------------------------------===//
14387abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao// Constant emission.
14397abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao//===----------------------------------------------------------------------===//
14407abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao
1441c53ade2889c85207e064e4c3d049383ffffb3319Chad Rosier/// lowerConstant - Lower the specified LLVM Constant to an MCExpr.
1442e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao///
1443c53ade2889c85207e064e4c3d049383ffffb3319Chad Rosierstatic const MCExpr *lowerConstant(const Constant *CV, AsmPrinter &AP) {
1444e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  MCContext &Ctx = AP.OutContext;
144583d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
1446e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  if (CV->isNullValue() || isa<UndefValue>(CV))
1447e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    return MCConstantExpr::Create(0, Ctx);
1448e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
1449e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV))
1450e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    return MCConstantExpr::Create(CI->getZExtValue(), Ctx);
145183d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
1452e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  if (const GlobalValue *GV = dyn_cast<GlobalValue>(CV))
14537abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    return MCSymbolRefExpr::Create(AP.Mang->getSymbol(GV), Ctx);
1454021fd61be69c5a763a5d32bc1912d5ecc83bb96bBill Wendling
1455e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  if (const BlockAddress *BA = dyn_cast<BlockAddress>(CV))
1456e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    return MCSymbolRefExpr::Create(AP.GetBlockAddressSymbol(BA), Ctx);
145783d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
1458e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV);
1459e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  if (CE == 0) {
1460e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    llvm_unreachable("Unknown constant value to lower!");
1461e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  }
146283d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
1463e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  switch (CE->getOpcode()) {
1464e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  default:
1465e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    // If the code isn't optimized, there may be outstanding folding
1466e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    // opportunities. Attempt to fold the expression using TargetData as a
1467e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    // last resort before giving up.
1468e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    if (Constant *C =
1469e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao          ConstantFoldConstantExpression(CE, AP.TM.getTargetData()))
1470e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      if (C != CE)
1471c53ade2889c85207e064e4c3d049383ffffb3319Chad Rosier        return lowerConstant(C, AP);
1472a3f4d8febfda9cdfaf0184f7faa86d5b9b4fb7f2Dan Gohman
1473a3f4d8febfda9cdfaf0184f7faa86d5b9b4fb7f2Dan Gohman    // Otherwise report the problem to the user.
1474a3f4d8febfda9cdfaf0184f7faa86d5b9b4fb7f2Dan Gohman    {
1475a3f4d8febfda9cdfaf0184f7faa86d5b9b4fb7f2Dan Gohman      std::string S;
1476a3f4d8febfda9cdfaf0184f7faa86d5b9b4fb7f2Dan Gohman      raw_string_ostream OS(S);
1477a3f4d8febfda9cdfaf0184f7faa86d5b9b4fb7f2Dan Gohman      OS << "Unsupported expression in static initializer: ";
1478a3f4d8febfda9cdfaf0184f7faa86d5b9b4fb7f2Dan Gohman      WriteAsOperand(OS, CE, /*PrintType=*/false,
1479a3f4d8febfda9cdfaf0184f7faa86d5b9b4fb7f2Dan Gohman                     !AP.MF ? 0 : AP.MF->getFunction()->getParent());
1480a3f4d8febfda9cdfaf0184f7faa86d5b9b4fb7f2Dan Gohman      report_fatal_error(OS.str());
1481a3f4d8febfda9cdfaf0184f7faa86d5b9b4fb7f2Dan Gohman    }
1482e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  case Instruction::GetElementPtr: {
1483e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    const TargetData &TD = *AP.TM.getTargetData();
1484e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    // Generate a symbolic expression for the byte address
1485e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    const Constant *PtrVal = CE->getOperand(0);
1486e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    SmallVector<Value*, 8> IdxVec(CE->op_begin()+1, CE->op_end());
14878fbbb3980755d74539a0aed02bc18842ed2bd18dJay Foad    int64_t Offset = TD.getIndexedOffset(PtrVal->getType(), IdxVec);
148883d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
1489c53ade2889c85207e064e4c3d049383ffffb3319Chad Rosier    const MCExpr *Base = lowerConstant(CE->getOperand(0), AP);
1490e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    if (Offset == 0)
1491e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      return Base;
149283d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
1493e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    // Truncate/sext the offset to the pointer size.
14941144af3c9b4da48cd581156e05b24261c8de366aRichard Smith    unsigned Width = TD.getPointerSizeInBits();
14951144af3c9b4da48cd581156e05b24261c8de366aRichard Smith    if (Width < 64)
14961144af3c9b4da48cd581156e05b24261c8de366aRichard Smith      Offset = SignExtend64(Offset, Width);
149783d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
1498e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    return MCBinaryExpr::CreateAdd(Base, MCConstantExpr::Create(Offset, Ctx),
1499e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                                   Ctx);
1500e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  }
150183d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
1502e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  case Instruction::Trunc:
1503e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    // We emit the value and depend on the assembler to truncate the generated
1504e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    // expression properly.  This is important for differences between
1505e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    // blockaddress labels.  Since the two labels are in the same function, it
1506e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    // is reasonable to treat their delta as a 32-bit value.
1507e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    // FALL THROUGH.
1508e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  case Instruction::BitCast:
1509c53ade2889c85207e064e4c3d049383ffffb3319Chad Rosier    return lowerConstant(CE->getOperand(0), AP);
1510e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
1511e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  case Instruction::IntToPtr: {
1512e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    const TargetData &TD = *AP.TM.getTargetData();
1513e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    // Handle casts to pointers by changing them into casts to the appropriate
1514e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    // integer type.  This promotes constant folding and simplifies this code.
1515e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    Constant *Op = CE->getOperand(0);
1516e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    Op = ConstantExpr::getIntegerCast(Op, TD.getIntPtrType(CV->getContext()),
1517e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                                      false/*ZExt*/);
1518c53ade2889c85207e064e4c3d049383ffffb3319Chad Rosier    return lowerConstant(Op, AP);
1519e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  }
152083d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
1521e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  case Instruction::PtrToInt: {
1522e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    const TargetData &TD = *AP.TM.getTargetData();
1523e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    // Support only foldable casts to/from pointers that can be eliminated by
1524e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    // changing the pointer to the appropriately sized integer type.
1525e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    Constant *Op = CE->getOperand(0);
1526db125cfaf57cc83e7dd7453de2d509bc8efd0e5eChris Lattner    Type *Ty = CE->getType();
1527e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
1528c53ade2889c85207e064e4c3d049383ffffb3319Chad Rosier    const MCExpr *OpExpr = lowerConstant(Op, AP);
1529e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
1530e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    // We can emit the pointer value into this slot if the slot is an
1531e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    // integer slot equal to the size of the pointer.
1532e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    if (TD.getTypeAllocSize(Ty) == TD.getTypeAllocSize(Op->getType()))
1533e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      return OpExpr;
1534e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
1535e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    // Otherwise the pointer is smaller than the resultant integer, mask off
1536e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    // the high bits so we are sure to get a proper truncation if the input is
1537e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    // a constant expr.
1538e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    unsigned InBits = TD.getTypeAllocSizeInBits(Op->getType());
1539e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    const MCExpr *MaskExpr = MCConstantExpr::Create(~0ULL >> (64-InBits), Ctx);
1540e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    return MCBinaryExpr::CreateAnd(OpExpr, MaskExpr, Ctx);
1541e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  }
154283d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
1543e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  // The MC library also has a right-shift operator, but it isn't consistently
1544e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  // signed or unsigned between different targets.
1545e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  case Instruction::Add:
1546e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  case Instruction::Sub:
1547e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  case Instruction::Mul:
1548e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  case Instruction::SDiv:
1549e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  case Instruction::SRem:
1550e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  case Instruction::Shl:
1551e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  case Instruction::And:
1552e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  case Instruction::Or:
1553e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  case Instruction::Xor: {
1554c53ade2889c85207e064e4c3d049383ffffb3319Chad Rosier    const MCExpr *LHS = lowerConstant(CE->getOperand(0), AP);
1555c53ade2889c85207e064e4c3d049383ffffb3319Chad Rosier    const MCExpr *RHS = lowerConstant(CE->getOperand(1), AP);
1556e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    switch (CE->getOpcode()) {
1557e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    default: llvm_unreachable("Unknown binary operator constant cast expr");
1558e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    case Instruction::Add: return MCBinaryExpr::CreateAdd(LHS, RHS, Ctx);
1559e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    case Instruction::Sub: return MCBinaryExpr::CreateSub(LHS, RHS, Ctx);
1560e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    case Instruction::Mul: return MCBinaryExpr::CreateMul(LHS, RHS, Ctx);
1561e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    case Instruction::SDiv: return MCBinaryExpr::CreateDiv(LHS, RHS, Ctx);
1562e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    case Instruction::SRem: return MCBinaryExpr::CreateMod(LHS, RHS, Ctx);
1563e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    case Instruction::Shl: return MCBinaryExpr::CreateShl(LHS, RHS, Ctx);
1564e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    case Instruction::And: return MCBinaryExpr::CreateAnd(LHS, RHS, Ctx);
1565e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    case Instruction::Or:  return MCBinaryExpr::CreateOr (LHS, RHS, Ctx);
1566e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    case Instruction::Xor: return MCBinaryExpr::CreateXor(LHS, RHS, Ctx);
1567e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    }
1568e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  }
1569e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  }
1570e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao}
1571e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
1572c53ade2889c85207e064e4c3d049383ffffb3319Chad Rosierstatic void emitGlobalConstantImpl(const Constant *C, unsigned AddrSpace,
15737abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao                                   AsmPrinter &AP);
15747abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao
1575d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene/// isRepeatedByteSequence - Determine whether the given value is
1576d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene/// composed of a repeated sequence of identical bytes and return the
1577d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene/// byte value.  If it is not a repeated sequence, return -1.
15789e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattnerstatic int isRepeatedByteSequence(const ConstantDataSequential *V) {
15799e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner  StringRef Data = V->getRawDataValues();
15809e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner  assert(!Data.empty() && "Empty aggregates should be CAZ node");
15819e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner  char C = Data[0];
15829e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner  for (unsigned i = 1, e = Data.size(); i != e; ++i)
15839e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner    if (Data[i] != C) return -1;
1584beb05952ce27b4039c9d8bea929f154edeb19ca0Chandler Carruth  return static_cast<uint8_t>(C); // Ensure 255 is not returned as -1.
15859e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner}
15869e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner
15879e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner
15889e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner/// isRepeatedByteSequence - Determine whether the given value is
15899e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner/// composed of a repeated sequence of identical bytes and return the
15909e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner/// byte value.  If it is not a repeated sequence, return -1.
1591d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greenestatic int isRepeatedByteSequence(const Value *V, TargetMachine &TM) {
1592d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene
1593d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene  if (const ConstantInt *CI = dyn_cast<ConstantInt>(V)) {
1594d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene    if (CI->getBitWidth() > 64) return -1;
1595d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene
1596d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene    uint64_t Size = TM.getTargetData()->getTypeAllocSize(V->getType());
1597d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene    uint64_t Value = CI->getZExtValue();
1598d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene
1599d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene    // Make sure the constant is at least 8 bits long and has a power
1600d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene    // of 2 bit width.  This guarantees the constant bit width is
1601d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene    // always a multiple of 8 bits, avoiding issues with padding out
1602d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene    // to Size and other such corner cases.
1603d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene    if (CI->getBitWidth() < 8 || !isPowerOf2_64(CI->getBitWidth())) return -1;
1604d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene
1605d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene    uint8_t Byte = static_cast<uint8_t>(Value);
1606d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene
1607d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene    for (unsigned i = 1; i < Size; ++i) {
1608d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene      Value >>= 8;
1609d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene      if (static_cast<uint8_t>(Value) != Byte) return -1;
1610d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene    }
1611d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene    return Byte;
1612d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene  }
1613d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene  if (const ConstantArray *CA = dyn_cast<ConstantArray>(V)) {
1614d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene    // Make sure all array elements are sequences of the same repeated
1615d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene    // byte.
16169e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner    assert(CA->getNumOperands() != 0 && "Should be a CAZ");
1617d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene    int Byte = isRepeatedByteSequence(CA->getOperand(0), TM);
1618d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene    if (Byte == -1) return -1;
1619d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene
1620d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene    for (unsigned i = 1, e = CA->getNumOperands(); i != e; ++i) {
1621d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene      int ThisByte = isRepeatedByteSequence(CA->getOperand(i), TM);
1622d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene      if (ThisByte == -1) return -1;
1623d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene      if (Byte != ThisByte) return -1;
1624d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene    }
1625d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene    return Byte;
1626d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene  }
16279e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner
16289e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner  if (const ConstantDataSequential *CDS = dyn_cast<ConstantDataSequential>(V))
16299e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner    return isRepeatedByteSequence(CDS);
1630d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene
1631d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene  return -1;
1632d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene}
1633d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene
1634c53ade2889c85207e064e4c3d049383ffffb3319Chad Rosierstatic void emitGlobalConstantDataSequential(const ConstantDataSequential *CDS,
16359e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner                                             unsigned AddrSpace,AsmPrinter &AP){
16369e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner
16379e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner  // See if we can aggregate this into a .fill, if so, emit it as such.
16389e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner  int Value = isRepeatedByteSequence(CDS, AP.TM);
16399e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner  if (Value != -1) {
16409e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner    uint64_t Bytes = AP.TM.getTargetData()->getTypeAllocSize(CDS->getType());
1641c63352f6336ab67cdba6d4702dc2bed5fdca1091Chris Lattner    // Don't emit a 1-byte object as a .fill.
1642c63352f6336ab67cdba6d4702dc2bed5fdca1091Chris Lattner    if (Bytes > 1)
1643c63352f6336ab67cdba6d4702dc2bed5fdca1091Chris Lattner      return AP.OutStreamer.EmitFill(Bytes, Value, AddrSpace);
16449e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner  }
16459e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner
16469e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner  // If this can be emitted with .ascii/.asciz, emit it as such.
16479e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner  if (CDS->isString())
16489e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner    return AP.OutStreamer.EmitBytes(CDS->getAsString(), AddrSpace);
16499e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner
16509e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner  // Otherwise, emit the values in successive locations.
16519e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner  unsigned ElementByteSize = CDS->getElementByteSize();
16529e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner  if (isa<IntegerType>(CDS->getElementType())) {
16530f193b8a6846dab25323788638e760ae03b7cd87Chris Lattner    for (unsigned i = 0, e = CDS->getNumElements(); i != e; ++i) {
1654b66fb5acbe4bfde5264fdbbfe7f9f478ed94c68dChris Lattner      if (AP.isVerbose())
1655b66fb5acbe4bfde5264fdbbfe7f9f478ed94c68dChris Lattner        AP.OutStreamer.GetCommentOS() << format("0x%" PRIx64 "\n",
1656b66fb5acbe4bfde5264fdbbfe7f9f478ed94c68dChris Lattner                                                CDS->getElementAsInteger(i));
16579e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner      AP.OutStreamer.EmitIntValue(CDS->getElementAsInteger(i),
16589e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner                                  ElementByteSize, AddrSpace);
1659d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene    }
16606e64c381daa30a63608bfa3443e67c39e6df2d64Chris Lattner  } else if (ElementByteSize == 4) {
16616e64c381daa30a63608bfa3443e67c39e6df2d64Chris Lattner    // FP Constants are printed as integer constants to avoid losing
16626e64c381daa30a63608bfa3443e67c39e6df2d64Chris Lattner    // precision.
16636e64c381daa30a63608bfa3443e67c39e6df2d64Chris Lattner    assert(CDS->getElementType()->isFloatTy());
16640f193b8a6846dab25323788638e760ae03b7cd87Chris Lattner    for (unsigned i = 0, e = CDS->getNumElements(); i != e; ++i) {
16659e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner      union {
16669e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner        float F;
16679e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner        uint32_t I;
16689e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner      };
16699e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner
16709e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner      F = CDS->getElementAsFloat(i);
16719e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner      if (AP.isVerbose())
16729e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner        AP.OutStreamer.GetCommentOS() << "float " << F << '\n';
16739e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner      AP.OutStreamer.EmitIntValue(I, 4, AddrSpace);
16749e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner    }
16756e64c381daa30a63608bfa3443e67c39e6df2d64Chris Lattner  } else {
16766e64c381daa30a63608bfa3443e67c39e6df2d64Chris Lattner    assert(CDS->getElementType()->isDoubleTy());
16776e64c381daa30a63608bfa3443e67c39e6df2d64Chris Lattner    for (unsigned i = 0, e = CDS->getNumElements(); i != e; ++i) {
16786e64c381daa30a63608bfa3443e67c39e6df2d64Chris Lattner      union {
16796e64c381daa30a63608bfa3443e67c39e6df2d64Chris Lattner        double F;
16806e64c381daa30a63608bfa3443e67c39e6df2d64Chris Lattner        uint64_t I;
16816e64c381daa30a63608bfa3443e67c39e6df2d64Chris Lattner      };
16826e64c381daa30a63608bfa3443e67c39e6df2d64Chris Lattner
16836e64c381daa30a63608bfa3443e67c39e6df2d64Chris Lattner      F = CDS->getElementAsDouble(i);
16846e64c381daa30a63608bfa3443e67c39e6df2d64Chris Lattner      if (AP.isVerbose())
16856e64c381daa30a63608bfa3443e67c39e6df2d64Chris Lattner        AP.OutStreamer.GetCommentOS() << "double " << F << '\n';
16866e64c381daa30a63608bfa3443e67c39e6df2d64Chris Lattner      AP.OutStreamer.EmitIntValue(I, 8, AddrSpace);
1687d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene    }
1688e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  }
168983d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
16906e64c381daa30a63608bfa3443e67c39e6df2d64Chris Lattner  const TargetData &TD = *AP.TM.getTargetData();
16916e64c381daa30a63608bfa3443e67c39e6df2d64Chris Lattner  unsigned Size = TD.getTypeAllocSize(CDS->getType());
16926e64c381daa30a63608bfa3443e67c39e6df2d64Chris Lattner  unsigned EmittedSize = TD.getTypeAllocSize(CDS->getType()->getElementType()) *
16936e64c381daa30a63608bfa3443e67c39e6df2d64Chris Lattner                        CDS->getNumElements();
16946e64c381daa30a63608bfa3443e67c39e6df2d64Chris Lattner  if (unsigned Padding = Size - EmittedSize)
16956e64c381daa30a63608bfa3443e67c39e6df2d64Chris Lattner    AP.OutStreamer.EmitZeros(Padding, AddrSpace);
16966e64c381daa30a63608bfa3443e67c39e6df2d64Chris Lattner
16979e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner}
1698e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
1699c53ade2889c85207e064e4c3d049383ffffb3319Chad Rosierstatic void emitGlobalConstantArray(const ConstantArray *CA, unsigned AddrSpace,
170091093ecf0fed6f007e08f1a4531cdb6f438672a2Chris Lattner                                    AsmPrinter &AP) {
170118c7f80b3e83ab584bd8572695a3cde8bafd9d3cChris Lattner  // See if we can aggregate some values.  Make sure it can be
170218c7f80b3e83ab584bd8572695a3cde8bafd9d3cChris Lattner  // represented as a series of bytes of the constant value.
170318c7f80b3e83ab584bd8572695a3cde8bafd9d3cChris Lattner  int Value = isRepeatedByteSequence(CA, AP.TM);
1704d92e2e4f88fccd4b3a497d8d9eade7bfd8564798David Greene
170518c7f80b3e83ab584bd8572695a3cde8bafd9d3cChris Lattner  if (Value != -1) {
170618c7f80b3e83ab584bd8572695a3cde8bafd9d3cChris Lattner    uint64_t Bytes = AP.TM.getTargetData()->getTypeAllocSize(CA->getType());
170718c7f80b3e83ab584bd8572695a3cde8bafd9d3cChris Lattner    AP.OutStreamer.EmitFill(Bytes, Value, AddrSpace);
170818c7f80b3e83ab584bd8572695a3cde8bafd9d3cChris Lattner  }
170918c7f80b3e83ab584bd8572695a3cde8bafd9d3cChris Lattner  else {
171018c7f80b3e83ab584bd8572695a3cde8bafd9d3cChris Lattner    for (unsigned i = 0, e = CA->getNumOperands(); i != e; ++i)
1711c53ade2889c85207e064e4c3d049383ffffb3319Chad Rosier      emitGlobalConstantImpl(CA->getOperand(i), AddrSpace, AP);
171200d448a341175556ebd86af68219f5b90b7145a3Dan Gohman  }
1713e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao}
1714e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
1715c53ade2889c85207e064e4c3d049383ffffb3319Chad Rosierstatic void emitGlobalConstantVector(const ConstantVector *CV,
1716e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                                     unsigned AddrSpace, AsmPrinter &AP) {
1717e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  for (unsigned i = 0, e = CV->getType()->getNumElements(); i != e; ++i)
1718c53ade2889c85207e064e4c3d049383ffffb3319Chad Rosier    emitGlobalConstantImpl(CV->getOperand(i), AddrSpace, AP);
17195b7ac1402f3c84a751eac96838d4b9676723f0c8Nick Lewycky
17205b7ac1402f3c84a751eac96838d4b9676723f0c8Nick Lewycky  const TargetData &TD = *AP.TM.getTargetData();
17215b7ac1402f3c84a751eac96838d4b9676723f0c8Nick Lewycky  unsigned Size = TD.getTypeAllocSize(CV->getType());
17225b7ac1402f3c84a751eac96838d4b9676723f0c8Nick Lewycky  unsigned EmittedSize = TD.getTypeAllocSize(CV->getType()->getElementType()) *
17235b7ac1402f3c84a751eac96838d4b9676723f0c8Nick Lewycky                         CV->getType()->getNumElements();
17245b7ac1402f3c84a751eac96838d4b9676723f0c8Nick Lewycky  if (unsigned Padding = Size - EmittedSize)
17255b7ac1402f3c84a751eac96838d4b9676723f0c8Nick Lewycky    AP.OutStreamer.EmitZeros(Padding, AddrSpace);
1726e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao}
1727e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
1728c53ade2889c85207e064e4c3d049383ffffb3319Chad Rosierstatic void emitGlobalConstantStruct(const ConstantStruct *CS,
1729e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                                     unsigned AddrSpace, AsmPrinter &AP) {
1730e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  // Print the fields in successive locations. Pad to align if needed!
1731e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  const TargetData *TD = AP.TM.getTargetData();
1732e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  unsigned Size = TD->getTypeAllocSize(CS->getType());
1733e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  const StructLayout *Layout = TD->getStructLayout(CS->getType());
1734e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  uint64_t SizeSoFar = 0;
1735e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  for (unsigned i = 0, e = CS->getNumOperands(); i != e; ++i) {
1736e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    const Constant *Field = CS->getOperand(i);
1737e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
1738e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    // Check if padding is needed and insert one or more 0s.
1739e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    uint64_t FieldSize = TD->getTypeAllocSize(Field->getType());
1740e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    uint64_t PadSize = ((i == e-1 ? Size : Layout->getElementOffset(i+1))
1741e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                        - Layout->getElementOffset(i)) - FieldSize;
1742e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    SizeSoFar += FieldSize + PadSize;
1743e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
1744e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    // Now print the actual field value.
1745c53ade2889c85207e064e4c3d049383ffffb3319Chad Rosier    emitGlobalConstantImpl(Field, AddrSpace, AP);
1746e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
1747e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    // Insert padding - this may include padding to increase the size of the
1748e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    // current field up to the ABI size (if the struct is not packed) as well
1749e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    // as padding to ensure that the next field starts at the right offset.
1750e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    AP.OutStreamer.EmitZeros(PadSize, AddrSpace);
1751e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  }
1752e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  assert(SizeSoFar == Layout->getSizeInBytes() &&
1753e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao         "Layout of constant struct may be incorrect!");
1754e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao}
1755e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
1756c53ade2889c85207e064e4c3d049383ffffb3319Chad Rosierstatic void emitGlobalConstantFP(const ConstantFP *CFP, unsigned AddrSpace,
1757e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                                 AsmPrinter &AP) {
1758e3376ecd504300ae529c902135f51baffbdc2824Dan Gohman  if (CFP->getType()->isHalfTy()) {
17597abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    if (AP.isVerbose()) {
1760e3376ecd504300ae529c902135f51baffbdc2824Dan Gohman      SmallString<10> Str;
1761e3376ecd504300ae529c902135f51baffbdc2824Dan Gohman      CFP->getValueAPF().toString(Str);
1762e3376ecd504300ae529c902135f51baffbdc2824Dan Gohman      AP.OutStreamer.GetCommentOS() << "half " << Str << '\n';
1763e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    }
1764e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    uint64_t Val = CFP->getValueAPF().bitcastToAPInt().getZExtValue();
1765e3376ecd504300ae529c902135f51baffbdc2824Dan Gohman    AP.OutStreamer.EmitIntValue(Val, 2, AddrSpace);
1766e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    return;
1767e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  }
176883d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
1769e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  if (CFP->getType()->isFloatTy()) {
17707abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    if (AP.isVerbose()) {
1771e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      float Val = CFP->getValueAPF().convertToFloat();
17727c0bc008f1b1f8185f879bd956ef0b5f361638cbJim Grosbach      uint64_t IntVal = CFP->getValueAPF().bitcastToAPInt().getZExtValue();
17737c0bc008f1b1f8185f879bd956ef0b5f361638cbJim Grosbach      AP.OutStreamer.GetCommentOS() << "float " << Val << '\n'
17747c0bc008f1b1f8185f879bd956ef0b5f361638cbJim Grosbach                                    << " (" << format("0x%x", IntVal) << ")\n";
1775e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    }
1776e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    uint64_t Val = CFP->getValueAPF().bitcastToAPInt().getZExtValue();
1777e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    AP.OutStreamer.EmitIntValue(Val, 4, AddrSpace);
1778e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    return;
1779e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  }
178083d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
1781e3376ecd504300ae529c902135f51baffbdc2824Dan Gohman  // FP Constants are printed as integer constants to avoid losing
1782e3376ecd504300ae529c902135f51baffbdc2824Dan Gohman  // precision.
1783e3376ecd504300ae529c902135f51baffbdc2824Dan Gohman  if (CFP->getType()->isDoubleTy()) {
1784e3376ecd504300ae529c902135f51baffbdc2824Dan Gohman    if (AP.isVerbose()) {
1785e3376ecd504300ae529c902135f51baffbdc2824Dan Gohman      double Val = CFP->getValueAPF().convertToDouble();
17867c0bc008f1b1f8185f879bd956ef0b5f361638cbJim Grosbach      uint64_t IntVal = CFP->getValueAPF().bitcastToAPInt().getZExtValue();
17877c0bc008f1b1f8185f879bd956ef0b5f361638cbJim Grosbach      AP.OutStreamer.GetCommentOS() << "double " << Val << '\n'
17887c0bc008f1b1f8185f879bd956ef0b5f361638cbJim Grosbach                                    << " (" << format("0x%lx", IntVal) << ")\n";
1789e3376ecd504300ae529c902135f51baffbdc2824Dan Gohman    }
1790e3376ecd504300ae529c902135f51baffbdc2824Dan Gohman
1791e3376ecd504300ae529c902135f51baffbdc2824Dan Gohman    uint64_t Val = CFP->getValueAPF().bitcastToAPInt().getZExtValue();
1792e3376ecd504300ae529c902135f51baffbdc2824Dan Gohman    AP.OutStreamer.EmitIntValue(Val, 8, AddrSpace);
1793e3376ecd504300ae529c902135f51baffbdc2824Dan Gohman    return;
1794e3376ecd504300ae529c902135f51baffbdc2824Dan Gohman  }
1795e3376ecd504300ae529c902135f51baffbdc2824Dan Gohman
1796e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  if (CFP->getType()->isX86_FP80Ty()) {
1797e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    // all long double variants are printed as hex
17987abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    // API needed to prevent premature destruction
1799e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    APInt API = CFP->getValueAPF().bitcastToAPInt();
1800e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    const uint64_t *p = API.getRawData();
18017abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    if (AP.isVerbose()) {
1802e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      // Convert to double so we can print the approximate val as a comment.
1803e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      APFloat DoubleVal = CFP->getValueAPF();
1804e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      bool ignored;
1805e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      DoubleVal.convert(APFloat::IEEEdouble, APFloat::rmNearestTiesToEven,
1806e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                        &ignored);
1807e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      AP.OutStreamer.GetCommentOS() << "x86_fp80 ~= "
1808e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao        << DoubleVal.convertToDouble() << '\n';
1809e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    }
181083d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
1811e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    if (AP.TM.getTargetData()->isBigEndian()) {
1812e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      AP.OutStreamer.EmitIntValue(p[1], 2, AddrSpace);
1813e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      AP.OutStreamer.EmitIntValue(p[0], 8, AddrSpace);
1814e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    } else {
1815e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      AP.OutStreamer.EmitIntValue(p[0], 8, AddrSpace);
1816e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      AP.OutStreamer.EmitIntValue(p[1], 2, AddrSpace);
1817e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    }
181883d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
1819e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    // Emit the tail padding for the long double.
1820e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    const TargetData &TD = *AP.TM.getTargetData();
1821e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    AP.OutStreamer.EmitZeros(TD.getTypeAllocSize(CFP->getType()) -
1822e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                             TD.getTypeStoreSize(CFP->getType()), AddrSpace);
1823e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    return;
1824e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  }
182583d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
1826e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  assert(CFP->getType()->isPPC_FP128Ty() &&
1827e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao         "Floating point constant type not handled");
18287abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  // All long double variants are printed as hex
18297abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  // API needed to prevent premature destruction.
1830e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  APInt API = CFP->getValueAPF().bitcastToAPInt();
1831e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  const uint64_t *p = API.getRawData();
1832e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  if (AP.TM.getTargetData()->isBigEndian()) {
1833e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    AP.OutStreamer.EmitIntValue(p[0], 8, AddrSpace);
1834e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    AP.OutStreamer.EmitIntValue(p[1], 8, AddrSpace);
1835e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  } else {
1836e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    AP.OutStreamer.EmitIntValue(p[1], 8, AddrSpace);
1837e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    AP.OutStreamer.EmitIntValue(p[0], 8, AddrSpace);
1838e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  }
1839e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao}
1840e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
1841c53ade2889c85207e064e4c3d049383ffffb3319Chad Rosierstatic void emitGlobalConstantLargeInt(const ConstantInt *CI,
1842e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                                       unsigned AddrSpace, AsmPrinter &AP) {
1843e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  const TargetData *TD = AP.TM.getTargetData();
1844e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  unsigned BitWidth = CI->getBitWidth();
1845e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  assert((BitWidth & 63) == 0 && "only support multiples of 64-bits");
1846e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
1847e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  // We don't expect assemblers to support integer data directives
1848e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  // for more than 64 bits, so we emit the data in at most 64-bit
1849e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  // quantities at a time.
1850e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  const uint64_t *RawData = CI->getValue().getRawData();
1851e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  for (unsigned i = 0, e = BitWidth / 64; i != e; ++i) {
1852e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    uint64_t Val = TD->isBigEndian() ? RawData[e - i - 1] : RawData[i];
1853e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    AP.OutStreamer.EmitIntValue(Val, 8, AddrSpace);
1854e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  }
1855e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao}
1856e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
1857c53ade2889c85207e064e4c3d049383ffffb3319Chad Rosierstatic void emitGlobalConstantImpl(const Constant *CV, unsigned AddrSpace,
18587abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao                                   AsmPrinter &AP) {
185921e42d0ea55c31ac4d57578f5116fa606d5c87eeBill Wendling  const TargetData *TD = AP.TM.getTargetData();
186021e42d0ea55c31ac4d57578f5116fa606d5c87eeBill Wendling  uint64_t Size = TD->getTypeAllocSize(CV->getType());
186121e42d0ea55c31ac4d57578f5116fa606d5c87eeBill Wendling  if (isa<ConstantAggregateZero>(CV) || isa<UndefValue>(CV))
18627abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    return AP.OutStreamer.EmitZeros(Size, AddrSpace);
1863e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
1864e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  if (const ConstantInt *CI = dyn_cast<ConstantInt>(CV)) {
1865e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    switch (Size) {
1866e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    case 1:
1867e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    case 2:
1868e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    case 4:
1869e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    case 8:
18707abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao      if (AP.isVerbose())
18714eb73c59bcd1055e9a3f324d836ce3898fbb7c81Benjamin Kramer        AP.OutStreamer.GetCommentOS() << format("0x%" PRIx64 "\n",
18724eb73c59bcd1055e9a3f324d836ce3898fbb7c81Benjamin Kramer                                                CI->getZExtValue());
1873021fd61be69c5a763a5d32bc1912d5ecc83bb96bBill Wendling      AP.OutStreamer.EmitIntValue(CI->getZExtValue(), Size, AddrSpace);
1874e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      return;
1875e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    default:
1876c53ade2889c85207e064e4c3d049383ffffb3319Chad Rosier      emitGlobalConstantLargeInt(CI, AddrSpace, AP);
1877e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      return;
1878e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    }
1879e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  }
188083d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
1881e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  if (const ConstantFP *CFP = dyn_cast<ConstantFP>(CV))
1882c53ade2889c85207e064e4c3d049383ffffb3319Chad Rosier    return emitGlobalConstantFP(CFP, AddrSpace, AP);
1883e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
1884e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  if (isa<ConstantPointerNull>(CV)) {
18857abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    AP.OutStreamer.EmitIntValue(0, Size, AddrSpace);
1886e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    return;
1887e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  }
188883d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
18899e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner  if (const ConstantDataSequential *CDS = dyn_cast<ConstantDataSequential>(CV))
1890c53ade2889c85207e064e4c3d049383ffffb3319Chad Rosier    return emitGlobalConstantDataSequential(CDS, AddrSpace, AP);
18919e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner
18929e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner  if (const ConstantArray *CVA = dyn_cast<ConstantArray>(CV))
1893c53ade2889c85207e064e4c3d049383ffffb3319Chad Rosier    return emitGlobalConstantArray(CVA, AddrSpace, AP);
189483d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
18959e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner  if (const ConstantStruct *CVS = dyn_cast<ConstantStruct>(CV))
1896c53ade2889c85207e064e4c3d049383ffffb3319Chad Rosier    return emitGlobalConstantStruct(CVS, AddrSpace, AP);
18979e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner
189821e42d0ea55c31ac4d57578f5116fa606d5c87eeBill Wendling  if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CV)) {
189921e42d0ea55c31ac4d57578f5116fa606d5c87eeBill Wendling    // Look through bitcasts, which might not be able to be MCExpr'ized (e.g. of
190021e42d0ea55c31ac4d57578f5116fa606d5c87eeBill Wendling    // vectors).
19019e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner    if (CE->getOpcode() == Instruction::BitCast)
1902c53ade2889c85207e064e4c3d049383ffffb3319Chad Rosier      return emitGlobalConstantImpl(CE->getOperand(0), AddrSpace, AP);
190321e42d0ea55c31ac4d57578f5116fa606d5c87eeBill Wendling
190421e42d0ea55c31ac4d57578f5116fa606d5c87eeBill Wendling    if (Size > 8) {
190521e42d0ea55c31ac4d57578f5116fa606d5c87eeBill Wendling      // If the constant expression's size is greater than 64-bits, then we have
190621e42d0ea55c31ac4d57578f5116fa606d5c87eeBill Wendling      // to emit the value in chunks. Try to constant fold the value and emit it
190721e42d0ea55c31ac4d57578f5116fa606d5c87eeBill Wendling      // that way.
190821e42d0ea55c31ac4d57578f5116fa606d5c87eeBill Wendling      Constant *New = ConstantFoldConstantExpression(CE, TD);
190921e42d0ea55c31ac4d57578f5116fa606d5c87eeBill Wendling      if (New && New != CE)
1910c53ade2889c85207e064e4c3d049383ffffb3319Chad Rosier        return emitGlobalConstantImpl(New, AddrSpace, AP);
191121e42d0ea55c31ac4d57578f5116fa606d5c87eeBill Wendling    }
191221e42d0ea55c31ac4d57578f5116fa606d5c87eeBill Wendling  }
19139e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner
19149e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner  if (const ConstantVector *V = dyn_cast<ConstantVector>(CV))
1915c53ade2889c85207e064e4c3d049383ffffb3319Chad Rosier    return emitGlobalConstantVector(V, AddrSpace, AP);
19169e631da253bff90d9da5ace21bd73f1c838e72ebChris Lattner
1917e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  // Otherwise, it must be a ConstantExpr.  Lower it to an MCExpr, then emit it
1918e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  // thread the streamer with EmitValue.
1919c53ade2889c85207e064e4c3d049383ffffb3319Chad Rosier  AP.OutStreamer.EmitValue(lowerConstant(CV, AP), Size, AddrSpace);
1920e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao}
1921e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
19227abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao/// EmitGlobalConstant - Print a general LLVM constant to the .s file.
19237abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liaovoid AsmPrinter::EmitGlobalConstant(const Constant *CV, unsigned AddrSpace) {
19247abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  uint64_t Size = TM.getTargetData()->getTypeAllocSize(CV->getType());
19257abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  if (Size)
1926c53ade2889c85207e064e4c3d049383ffffb3319Chad Rosier    emitGlobalConstantImpl(CV, AddrSpace, *this);
19277abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  else if (MAI->hasSubsectionsViaSymbols()) {
19287abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    // If the global has zero size, emit a single byte so that two labels don't
19297abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    // look like they are at the same location.
19307abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    OutStreamer.EmitIntValue(0, 1, AddrSpace);
1931e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  }
1932e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao}
1933e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
19347abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liaovoid AsmPrinter::EmitMachineConstantPoolValue(MachineConstantPoolValue *MCPV) {
19357abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  // Target doesn't support this yet!
19367abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  llvm_unreachable("Target does not support EmitMachineConstantPoolValue");
1937e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao}
1938e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
19397abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liaovoid AsmPrinter::printOffset(int64_t Offset, raw_ostream &OS) const {
19407abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  if (Offset > 0)
19417abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    OS << '+' << Offset;
19427abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  else if (Offset < 0)
19437abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    OS << Offset;
1944e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao}
1945e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
19467abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao//===----------------------------------------------------------------------===//
19477abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao// Symbol Lowering Routines.
19487abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao//===----------------------------------------------------------------------===//
1949e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
19507abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao/// GetTempSymbol - Return the MCSymbol corresponding to the assembler
19517abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao/// temporary label with the specified stem and unique ID.
19527abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei LiaoMCSymbol *AsmPrinter::GetTempSymbol(StringRef Name, unsigned ID) const {
19537abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  return OutContext.GetOrCreateSymbol(Twine(MAI->getPrivateGlobalPrefix()) +
19547abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao                                      Name + Twine(ID));
1955e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao}
1956e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
19577abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao/// GetTempSymbol - Return an assembler temporary label with the specified
19587abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao/// stem.
19597abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei LiaoMCSymbol *AsmPrinter::GetTempSymbol(StringRef Name) const {
19607abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  return OutContext.GetOrCreateSymbol(Twine(MAI->getPrivateGlobalPrefix())+
19617abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao                                      Name);
1962e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao}
1963e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
1964e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
1965e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei LiaoMCSymbol *AsmPrinter::GetBlockAddressSymbol(const BlockAddress *BA) const {
19667abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  return MMI->getAddrLabelSymbol(BA->getBasicBlock());
1967e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao}
1968e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
19697abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei LiaoMCSymbol *AsmPrinter::GetBlockAddressSymbol(const BasicBlock *BB) const {
19707abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  return MMI->getAddrLabelSymbol(BB);
1971e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao}
1972e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
1973e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao/// GetCPISymbol - Return the symbol for the specified constant pool entry.
1974e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei LiaoMCSymbol *AsmPrinter::GetCPISymbol(unsigned CPID) const {
19757abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  return OutContext.GetOrCreateSymbol
19767abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    (Twine(MAI->getPrivateGlobalPrefix()) + "CPI" + Twine(getFunctionNumber())
19777abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao     + "_" + Twine(CPID));
1978e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao}
1979e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
1980e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao/// GetJTISymbol - Return the symbol for the specified jump table entry.
1981e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei LiaoMCSymbol *AsmPrinter::GetJTISymbol(unsigned JTID, bool isLinkerPrivate) const {
1982e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  return MF->getJTISymbol(JTID, OutContext, isLinkerPrivate);
1983e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao}
1984e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
1985e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao/// GetJTSetSymbol - Return the symbol for the specified jump table .set
1986e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao/// FIXME: privatize to AsmPrinter.
1987e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei LiaoMCSymbol *AsmPrinter::GetJTSetSymbol(unsigned UID, unsigned MBBID) const {
19887abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  return OutContext.GetOrCreateSymbol
19897abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  (Twine(MAI->getPrivateGlobalPrefix()) + Twine(getFunctionNumber()) + "_" +
19907abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao   Twine(UID) + "_set_" + Twine(MBBID));
1991e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao}
1992e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
1993e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao/// GetSymbolWithGlobalValueBase - Return the MCSymbol for a symbol with
1994e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao/// global value name as its base, with the specified suffix, and where the
1995e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao/// symbol is forced to have private linkage if ForcePrivate is true.
1996e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei LiaoMCSymbol *AsmPrinter::GetSymbolWithGlobalValueBase(const GlobalValue *GV,
1997e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                                                   StringRef Suffix,
1998e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                                                   bool ForcePrivate) const {
1999e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  SmallString<60> NameStr;
2000e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  Mang->getNameWithPrefix(NameStr, GV, ForcePrivate);
2001e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  NameStr.append(Suffix.begin(), Suffix.end());
2002e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  return OutContext.GetOrCreateSymbol(NameStr.str());
2003e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao}
2004e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
2005e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao/// GetExternalSymbolSymbol - Return the MCSymbol for the specified
2006e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao/// ExternalSymbol.
2007e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei LiaoMCSymbol *AsmPrinter::GetExternalSymbolSymbol(StringRef Sym) const {
2008e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  SmallString<60> NameStr;
2009e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  Mang->getNameWithPrefix(NameStr, Sym);
2010e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  return OutContext.GetOrCreateSymbol(NameStr.str());
201183d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach}
2012e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
2013e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
2014e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
2015e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao/// PrintParentLoopComment - Print comments about parent loops of this one.
2016e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liaostatic void PrintParentLoopComment(raw_ostream &OS, const MachineLoop *Loop,
2017e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                                   unsigned FunctionNumber) {
2018e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  if (Loop == 0) return;
2019e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  PrintParentLoopComment(OS, Loop->getParentLoop(), FunctionNumber);
2020e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  OS.indent(Loop->getLoopDepth()*2)
2021e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    << "Parent Loop BB" << FunctionNumber << "_"
2022e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    << Loop->getHeader()->getNumber()
2023e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    << " Depth=" << Loop->getLoopDepth() << '\n';
2024e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao}
2025e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
2026e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
2027e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao/// PrintChildLoopComment - Print comments about child loops within
2028e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao/// the loop for this basic block, with nesting.
2029e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liaostatic void PrintChildLoopComment(raw_ostream &OS, const MachineLoop *Loop,
2030e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                                  unsigned FunctionNumber) {
2031e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  // Add child loop information
2032e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  for (MachineLoop::iterator CL = Loop->begin(), E = Loop->end();CL != E; ++CL){
2033e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    OS.indent((*CL)->getLoopDepth()*2)
2034e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      << "Child Loop BB" << FunctionNumber << "_"
2035e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      << (*CL)->getHeader()->getNumber() << " Depth " << (*CL)->getLoopDepth()
2036e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      << '\n';
2037e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    PrintChildLoopComment(OS, *CL, FunctionNumber);
2038e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  }
2039e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao}
2040e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
2041c53ade2889c85207e064e4c3d049383ffffb3319Chad Rosier/// emitBasicBlockLoopComments - Pretty-print comments for basic blocks.
2042c53ade2889c85207e064e4c3d049383ffffb3319Chad Rosierstatic void emitBasicBlockLoopComments(const MachineBasicBlock &MBB,
20437abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao                                       const MachineLoopInfo *LI,
20447abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao                                       const AsmPrinter &AP) {
2045e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  // Add loop depth information
2046e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  const MachineLoop *Loop = LI->getLoopFor(&MBB);
2047e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  if (Loop == 0) return;
204883d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
2049e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  MachineBasicBlock *Header = Loop->getHeader();
2050e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  assert(Header && "No header for loop");
205183d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
2052e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  // If this block is not a loop header, just print out what is the loop header
2053e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  // and return.
2054e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  if (Header != &MBB) {
2055e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    AP.OutStreamer.AddComment("  in Loop: Header=BB" +
2056e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                              Twine(AP.getFunctionNumber())+"_" +
2057e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                              Twine(Loop->getHeader()->getNumber())+
2058e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao                              " Depth="+Twine(Loop->getLoopDepth()));
2059e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    return;
2060e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  }
206183d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
2062e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  // Otherwise, it is a loop header.  Print out information about child and
2063e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  // parent loops.
2064e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  raw_ostream &OS = AP.OutStreamer.GetCommentOS();
206583d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
206683d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach  PrintParentLoopComment(OS, Loop->getParentLoop(), AP.getFunctionNumber());
206783d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
2068e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  OS << "=>";
2069e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  OS.indent(Loop->getLoopDepth()*2-2);
207083d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
2071e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  OS << "This ";
2072e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  if (Loop->empty())
2073e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    OS << "Inner ";
2074e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  OS << "Loop Header: Depth=" + Twine(Loop->getLoopDepth()) << '\n';
207583d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
2076e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  PrintChildLoopComment(OS, Loop, AP.getFunctionNumber());
2077e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao}
2078e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
2079e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
2080e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao/// EmitBasicBlockStart - This method prints the label for the specified
2081e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao/// MachineBasicBlock, an alignment (if present) and a comment describing
2082e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao/// it if appropriate.
2083e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liaovoid AsmPrinter::EmitBasicBlockStart(const MachineBasicBlock *MBB) const {
2084e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  // Emit an alignment directive for this block, if needed.
2085e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  if (unsigned Align = MBB->getAlignment())
20868c741b8064f1116d8d8dc435b60b75abdf5c4d57Jakob Stoklund Olesen    EmitAlignment(Align);
2087e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
20887abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  // If the block has its address taken, emit any labels that were used to
20897abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  // reference the block.  It is possible that there is more than one label
20907abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  // here, because multiple LLVM BB's may have been RAUW'd to this block after
20917abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  // the references were generated.
2092e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  if (MBB->hasAddressTaken()) {
2093e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    const BasicBlock *BB = MBB->getBasicBlock();
20947abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    if (isVerbose())
20957abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao      OutStreamer.AddComment("Block address taken");
209683d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
20977abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    std::vector<MCSymbol*> Syms = MMI->getAddrLabelSymbolToEmit(BB);
20987abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao
20997abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    for (unsigned i = 0, e = Syms.size(); i != e; ++i)
21007abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao      OutStreamer.EmitLabel(Syms[i]);
2101e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  }
2102e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
2103c511c2827d9cebd16bc63041b5812f1fc5d57e06Jakob Stoklund Olesen  // Print some verbose block comments.
2104c511c2827d9cebd16bc63041b5812f1fc5d57e06Jakob Stoklund Olesen  if (isVerbose()) {
2105c511c2827d9cebd16bc63041b5812f1fc5d57e06Jakob Stoklund Olesen    if (const BasicBlock *BB = MBB->getBasicBlock())
2106c511c2827d9cebd16bc63041b5812f1fc5d57e06Jakob Stoklund Olesen      if (BB->hasName())
2107c511c2827d9cebd16bc63041b5812f1fc5d57e06Jakob Stoklund Olesen        OutStreamer.AddComment("%" + BB->getName());
2108c53ade2889c85207e064e4c3d049383ffffb3319Chad Rosier    emitBasicBlockLoopComments(*MBB, LI, *this);
2109c511c2827d9cebd16bc63041b5812f1fc5d57e06Jakob Stoklund Olesen  }
2110c511c2827d9cebd16bc63041b5812f1fc5d57e06Jakob Stoklund Olesen
2111e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  // Print the main label for the block.
2112e4454320b3cfffe926a487c33fbeb454366de2f8Shih-wei Liao  if (MBB->pred_empty() || isBlockOnlyReachableByFallthrough(MBB)) {
21137abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    if (isVerbose() && OutStreamer.hasRawTextSupport()) {
21147abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao      // NOTE: Want this comment at start of line, don't emit with AddComment.
21157abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao      OutStreamer.EmitRawText(Twine(MAI->getCommentString()) + " BB#" +
21167abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao                              Twine(MBB->getNumber()) + ":");
2117e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    }
2118e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  } else {
21197abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao    OutStreamer.EmitLabel(MBB->getSymbol());
2120e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  }
2121e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao}
2122e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
21235129bdecd87c518713765acd6998c80f9eef36a2Stuart Hastingsvoid AsmPrinter::EmitVisibility(MCSymbol *Sym, unsigned Visibility,
21245129bdecd87c518713765acd6998c80f9eef36a2Stuart Hastings                                bool IsDefinition) const {
2125e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  MCSymbolAttr Attr = MCSA_Invalid;
212683d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
2127e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  switch (Visibility) {
2128e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  default: break;
2129e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  case GlobalValue::HiddenVisibility:
21305129bdecd87c518713765acd6998c80f9eef36a2Stuart Hastings    if (IsDefinition)
21315129bdecd87c518713765acd6998c80f9eef36a2Stuart Hastings      Attr = MAI->getHiddenVisibilityAttr();
21325129bdecd87c518713765acd6998c80f9eef36a2Stuart Hastings    else
21335129bdecd87c518713765acd6998c80f9eef36a2Stuart Hastings      Attr = MAI->getHiddenDeclarationVisibilityAttr();
2134e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    break;
2135e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  case GlobalValue::ProtectedVisibility:
2136e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    Attr = MAI->getProtectedVisibilityAttr();
2137e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    break;
2138e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  }
2139e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
2140e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  if (Attr != MCSA_Invalid)
2141e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    OutStreamer.EmitSymbolAttribute(Sym, Attr);
2142e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao}
2143e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao
2144e4454320b3cfffe926a487c33fbeb454366de2f8Shih-wei Liao/// isBlockOnlyReachableByFallthough - Return true if the basic block has
2145e4454320b3cfffe926a487c33fbeb454366de2f8Shih-wei Liao/// exactly one predecessor and the control transfer mechanism between
2146e4454320b3cfffe926a487c33fbeb454366de2f8Shih-wei Liao/// the predecessor and this block is a fall-through.
21477abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liaobool AsmPrinter::
21487abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei LiaoisBlockOnlyReachableByFallthrough(const MachineBasicBlock *MBB) const {
2149e4454320b3cfffe926a487c33fbeb454366de2f8Shih-wei Liao  // If this is a landing pad, it isn't a fall through.  If it has no preds,
2150e4454320b3cfffe926a487c33fbeb454366de2f8Shih-wei Liao  // then nothing falls through to it.
2151e4454320b3cfffe926a487c33fbeb454366de2f8Shih-wei Liao  if (MBB->isLandingPad() || MBB->pred_empty())
2152e4454320b3cfffe926a487c33fbeb454366de2f8Shih-wei Liao    return false;
215383d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
2154e4454320b3cfffe926a487c33fbeb454366de2f8Shih-wei Liao  // If there isn't exactly one predecessor, it can't be a fall through.
2155e4454320b3cfffe926a487c33fbeb454366de2f8Shih-wei Liao  MachineBasicBlock::const_pred_iterator PI = MBB->pred_begin(), PI2 = PI;
2156e4454320b3cfffe926a487c33fbeb454366de2f8Shih-wei Liao  ++PI2;
2157e4454320b3cfffe926a487c33fbeb454366de2f8Shih-wei Liao  if (PI2 != MBB->pred_end())
2158e4454320b3cfffe926a487c33fbeb454366de2f8Shih-wei Liao    return false;
215983d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
2160e4454320b3cfffe926a487c33fbeb454366de2f8Shih-wei Liao  // The predecessor has to be immediately before this block.
21610fc3015ae8a70152895536ddd8395ce8f6219164Eli Friedman  MachineBasicBlock *Pred = *PI;
216283d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
2163e4454320b3cfffe926a487c33fbeb454366de2f8Shih-wei Liao  if (!Pred->isLayoutSuccessor(MBB))
2164e4454320b3cfffe926a487c33fbeb454366de2f8Shih-wei Liao    return false;
216583d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
2166e4454320b3cfffe926a487c33fbeb454366de2f8Shih-wei Liao  // If the block is completely empty, then it definitely does fall through.
2167e4454320b3cfffe926a487c33fbeb454366de2f8Shih-wei Liao  if (Pred->empty())
2168e4454320b3cfffe926a487c33fbeb454366de2f8Shih-wei Liao    return true;
216983d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
21700fc3015ae8a70152895536ddd8395ce8f6219164Eli Friedman  // Check the terminators in the previous blocks
21710fc3015ae8a70152895536ddd8395ce8f6219164Eli Friedman  for (MachineBasicBlock::iterator II = Pred->getFirstTerminator(),
21720fc3015ae8a70152895536ddd8395ce8f6219164Eli Friedman         IE = Pred->end(); II != IE; ++II) {
21730fc3015ae8a70152895536ddd8395ce8f6219164Eli Friedman    MachineInstr &MI = *II;
21740fc3015ae8a70152895536ddd8395ce8f6219164Eli Friedman
21750fc3015ae8a70152895536ddd8395ce8f6219164Eli Friedman    // If it is not a simple branch, we are in a table somewhere.
21765a96b3dad2f634c9081c8b2b6c2575441dc5a2bdEvan Cheng    if (!MI.isBranch() || MI.isIndirectBranch())
21770fc3015ae8a70152895536ddd8395ce8f6219164Eli Friedman      return false;
21780fc3015ae8a70152895536ddd8395ce8f6219164Eli Friedman
21790fc3015ae8a70152895536ddd8395ce8f6219164Eli Friedman    // If we are the operands of one of the branches, this is not
21800fc3015ae8a70152895536ddd8395ce8f6219164Eli Friedman    // a fall through.
21810fc3015ae8a70152895536ddd8395ce8f6219164Eli Friedman    for (MachineInstr::mop_iterator OI = MI.operands_begin(),
21820fc3015ae8a70152895536ddd8395ce8f6219164Eli Friedman           OE = MI.operands_end(); OI != OE; ++OI) {
21830fc3015ae8a70152895536ddd8395ce8f6219164Eli Friedman      const MachineOperand& OP = *OI;
2184aeb6da46ce7c55440215fca1fb11122ecddeec44Rafael Espindola      if (OP.isJTI())
2185aeb6da46ce7c55440215fca1fb11122ecddeec44Rafael Espindola        return false;
21860fc3015ae8a70152895536ddd8395ce8f6219164Eli Friedman      if (OP.isMBB() && OP.getMBB() == MBB)
21870fc3015ae8a70152895536ddd8395ce8f6219164Eli Friedman        return false;
21880fc3015ae8a70152895536ddd8395ce8f6219164Eli Friedman    }
21890fc3015ae8a70152895536ddd8395ce8f6219164Eli Friedman  }
21900fc3015ae8a70152895536ddd8395ce8f6219164Eli Friedman
21910fc3015ae8a70152895536ddd8395ce8f6219164Eli Friedman  return true;
2192e4454320b3cfffe926a487c33fbeb454366de2f8Shih-wei Liao}
2193e4454320b3cfffe926a487c33fbeb454366de2f8Shih-wei Liao
2194e4454320b3cfffe926a487c33fbeb454366de2f8Shih-wei Liao
2195e4454320b3cfffe926a487c33fbeb454366de2f8Shih-wei Liao
2196e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei LiaoGCMetadataPrinter *AsmPrinter::GetOrCreateGCPrinter(GCStrategy *S) {
2197e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  if (!S->usesMetadata())
2198e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    return 0;
21997abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao
22007abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  gcp_map_type &GCMap = getGCMap(GCMetadataPrinters);
22017abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  gcp_map_type::iterator GCPI = GCMap.find(S);
22027abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  if (GCPI != GCMap.end())
2203e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    return GCPI->second;
220483d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
2205e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  const char *Name = S->getName().c_str();
220683d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
2207e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao  for (GCMetadataPrinterRegistry::iterator
2208e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao         I = GCMetadataPrinterRegistry::begin(),
2209e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao         E = GCMetadataPrinterRegistry::end(); I != E; ++I)
2210e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    if (strcmp(Name, I->getName()) == 0) {
2211e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      GCMetadataPrinter *GMP = I->instantiate();
2212e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      GMP->S = S;
22137abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao      GCMap.insert(std::make_pair(S, GMP));
2214e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao      return GMP;
2215e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao    }
221683d808329b81ad7589ddc516566169b0331c25d1Jim Grosbach
22177abe37e4aee38cc79d91dd069a37d7e91d5bef53Shih-wei Liao  report_fatal_error("no GCMetadataPrinter registered for GC: " + Twine(Name));
2218e264f62ca09a8f65c87a46d562a4d0f9ec5d457Shih-wei Liao}
2219