SparcAsmPrinter.cpp revision 379e6c03695c635608b5dc17402b93a8f7475b13
177595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik//===-- SparcV8AsmPrinter.cpp - SparcV8 LLVM assembly writer --------------===//
277595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik//
377595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik//                     The LLVM Compiler Infrastructure
477595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik//
577595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik// This file was developed by the LLVM research group and is distributed under
677595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik// the University of Illinois Open Source License. See LICENSE.TXT for details.
78fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendling//
877595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik//===----------------------------------------------------------------------===//
977595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik//
108fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendling// This file contains a printer that converts from our internal representation
1177595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik// of machine-dependent LLVM code to GAS-format Sparc V8 assembly language.
1277595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik//
1377595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik//===----------------------------------------------------------------------===//
1477595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik
1577595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik#include "SparcV8.h"
16c13c9e5a9d288eac494a38f0710d34446167f940Rafael Espindola#include "SparcV8InstrInfo.h"
17cc48854d5d51a2d7557f1040a61f160ad86c9729Peter Collingbourne#include "llvm/Constants.h"
18cc48854d5d51a2d7557f1040a61f160ad86c9729Peter Collingbourne#include "llvm/DerivedTypes.h"
19cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines#include "llvm/Module.h"
20cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines#include "llvm/Assembly/Writer.h"
2177595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik#include "llvm/CodeGen/AsmPrinter.h"
22c13c9e5a9d288eac494a38f0710d34446167f940Rafael Espindola#include "llvm/CodeGen/MachineFunctionPass.h"
23c13c9e5a9d288eac494a38f0710d34446167f940Rafael Espindola#include "llvm/CodeGen/MachineConstantPool.h"
24c13c9e5a9d288eac494a38f0710d34446167f940Rafael Espindola#include "llvm/CodeGen/MachineInstr.h"
25c13c9e5a9d288eac494a38f0710d34446167f940Rafael Espindola#include "llvm/Target/TargetMachine.h"
26c13c9e5a9d288eac494a38f0710d34446167f940Rafael Espindola#include "llvm/Support/Mangler.h"
27c13c9e5a9d288eac494a38f0710d34446167f940Rafael Espindola#include "llvm/ADT/Statistic.h"
28c13c9e5a9d288eac494a38f0710d34446167f940Rafael Espindola#include "llvm/ADT/StringExtras.h"
29c13c9e5a9d288eac494a38f0710d34446167f940Rafael Espindola#include "llvm/Support/CommandLine.h"
30c13c9e5a9d288eac494a38f0710d34446167f940Rafael Espindola#include "llvm/Support/MathExtras.h"
31c13c9e5a9d288eac494a38f0710d34446167f940Rafael Espindola#include <cctype>
32c13c9e5a9d288eac494a38f0710d34446167f940Rafael Espindolausing namespace llvm;
33c13c9e5a9d288eac494a38f0710d34446167f940Rafael Espindola
3477595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledziknamespace {
358fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendling  Statistic<> EmittedInsts("asm-printer", "Number of machine instrs printed");
368fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendling
3777595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik  struct SparcV8AsmPrinter : public AsmPrinter {
3877595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik    SparcV8AsmPrinter(std::ostream &O, TargetMachine &TM) : AsmPrinter(O, TM) {
39cc48854d5d51a2d7557f1040a61f160ad86c9729Peter Collingbourne      Data16bitsDirective = "\t.half\t";
40cc48854d5d51a2d7557f1040a61f160ad86c9729Peter Collingbourne      Data32bitsDirective = "\t.word\t";
41cc48854d5d51a2d7557f1040a61f160ad86c9729Peter Collingbourne      Data64bitsDirective = 0;  // .xword is only supported by V9.
42cc48854d5d51a2d7557f1040a61f160ad86c9729Peter Collingbourne      ZeroDirective = 0;  // no .zero or .space!
430e95b3aba9b2039ae3af617e681aacca2ff81f79Rafael Espindola      CommentString = "!";
440e95b3aba9b2039ae3af617e681aacca2ff81f79Rafael Espindola      ConstantPoolSection = "\t.section \".rodata\",#alloc\n";
450e95b3aba9b2039ae3af617e681aacca2ff81f79Rafael Espindola    }
46cc48854d5d51a2d7557f1040a61f160ad86c9729Peter Collingbourne
47cc48854d5d51a2d7557f1040a61f160ad86c9729Peter Collingbourne    /// We name each basic block in a Function with a unique number, so
48cc48854d5d51a2d7557f1040a61f160ad86c9729Peter Collingbourne    /// that we can consistently refer to them later. This is cleared
49cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    /// at the beginning of each call to runOnMachineFunction().
50cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    ///
51cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    typedef std::map<const Value *, unsigned> ValueMapTy;
52cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    ValueMapTy NumberForBB;
53cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
54cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    virtual const char *getPassName() const {
55cc48854d5d51a2d7557f1040a61f160ad86c9729Peter Collingbourne      return "SparcV8 Assembly Printer";
56cc48854d5d51a2d7557f1040a61f160ad86c9729Peter Collingbourne    }
57cc48854d5d51a2d7557f1040a61f160ad86c9729Peter Collingbourne
58cc48854d5d51a2d7557f1040a61f160ad86c9729Peter Collingbourne    void printOperand(const MachineInstr *MI, int opNum);
59dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    void printMemOperand(const MachineInstr *MI, int opNum);
60dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    bool printInstruction(const MachineInstr *MI);  // autogenerated.
61dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    bool runOnMachineFunction(MachineFunction &F);
62dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    bool doInitialization(Module &M);
63dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    bool doFinalization(Module &M);
64dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  };
65dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} // end of anonymous namespace
66dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
67dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "SparcV8GenAsmWriter.inc"
68dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
69dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// createSparcV8CodePrinterPass - Returns a pass that prints the SparcV8
70dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// assembly code for a MachineFunction to the given output stream,
71dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// using the given target machine description.  This should work
72dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// regardless of whether the function is in SSA form.
73dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines///
74dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesFunctionPass *llvm::createSparcV8CodePrinterPass (std::ostream &o,
75dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines                                                  TargetMachine &tm) {
76dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  return new SparcV8AsmPrinter(o, tm);
778fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendling}
788fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendling
7977595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik/// runOnMachineFunction - This uses the printMachineInstruction()
8077595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik/// method to print assembly for each instruction.
818fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendling///
828fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendlingbool SparcV8AsmPrinter::runOnMachineFunction(MachineFunction &MF) {
8377595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik  SetupMachineFunction(MF);
8477595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik
8507d5aef3057b2e403b20d683e7477c93fde67d99Reid Kleckner  // Print out constants referenced by the function
868fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendling  EmitConstantPool(MF.getConstantPool());
8777595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik
8877595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik  // BBNumber is used here so that a given Printer will never give two
8907d5aef3057b2e403b20d683e7477c93fde67d99Reid Kleckner  // BBs the same name. (If you have a better way, please let me know!)
908fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendling  static unsigned BBNumber = 0;
91cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
92cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  O << "\n\n";
93cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  // What's my mangled name?
94cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  CurrentFnName = Mang->getValueName(MF.getFunction());
9577595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik
9677595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik  // Print out labels for the function.
9707d5aef3057b2e403b20d683e7477c93fde67d99Reid Kleckner  O << "\t.text\n";
988fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendling  O << "\t.align 16\n";
9977595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik  O << "\t.globl\t" << CurrentFnName << "\n";
10077595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik  O << "\t.type\t" << CurrentFnName << ", #function\n";
10107d5aef3057b2e403b20d683e7477c93fde67d99Reid Kleckner  O << CurrentFnName << ":\n";
1028fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendling
1038fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendling  // Number each basic block so that we can consistently refer to them
1048fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendling  // in PC-relative references.
105cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  NumberForBB.clear();
106cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines  for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
107cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines       I != E; ++I) {
108cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    NumberForBB[I->getBasicBlock()] = BBNumber++;
10977595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik  }
11077595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik
1118fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendling  // Print out code for the function.
112cc48854d5d51a2d7557f1040a61f160ad86c9729Peter Collingbourne  for (MachineFunction::const_iterator I = MF.begin(), E = MF.end();
11336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines       I != E; ++I) {
114cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    // Print a label for the basic block.
11577595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik    O << ".LBB" << Mang->getValueName(MF.getFunction ())
11677595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik      << "_" << I->getNumber () << ":\t! "
1178fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendling      << I->getBasicBlock ()->getName () << "\n";
118cc48854d5d51a2d7557f1040a61f160ad86c9729Peter Collingbourne    for (MachineBasicBlock::const_iterator II = I->begin(), E = I->end();
11936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines         II != E; ++II) {
120dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      // Print the assembly for the instruction.
121cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      O << "\t";
122b4cc031a3e1306fea74c9211d50c5cde6d9a8cd5Rafael Espindola      printInstruction(II);
12377595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik      ++EmittedInsts;
124f21b1058a194f411000bdd8000a8b675a7874056Rafael Espindola    }
125f21b1058a194f411000bdd8000a8b675a7874056Rafael Espindola  }
126f21b1058a194f411000bdd8000a8b675a7874056Rafael Espindola
1278fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendling  // We didn't modify anything.
128cc48854d5d51a2d7557f1040a61f160ad86c9729Peter Collingbourne  return false;
12936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
130cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines
131cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hinesvoid SparcV8AsmPrinter::printOperand(const MachineInstr *MI, int opNum) {
132f21b1058a194f411000bdd8000a8b675a7874056Rafael Espindola  const MachineOperand &MO = MI->getOperand (opNum);
133f21b1058a194f411000bdd8000a8b675a7874056Rafael Espindola  const MRegisterInfo &RI = *TM.getRegisterInfo();
1348fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendling  bool CloseParen = false;
135cc48854d5d51a2d7557f1040a61f160ad86c9729Peter Collingbourne  if (MI->getOpcode() == V8::SETHIi && !MO.isRegister() && !MO.isImmediate()) {
13636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    O << "%hi(";
137cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines    CloseParen = true;
13877595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik  } else if (MI->getOpcode() ==V8::ORri &&!MO.isRegister() &&!MO.isImmediate())
13977595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik  {
14036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    O << "%lo(";
14136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    CloseParen = true;
14236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
14336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  switch (MO.getType()) {
14436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case MachineOperand::MO_VirtualRegister:
145dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (Value *V = MO.getVRegValueOrNull()) {
146cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      O << "<" << V->getName() << ">";
14736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      break;
14836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    }
149dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    // FALLTHROUGH
15077595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik  case MachineOperand::MO_MachineRegister:
1518fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendling    if (MRegisterInfo::isPhysicalRegister(MO.getReg()))
152cd81d94322a39503e4a3e87b6ee03d4fcb3465fbStephen Hines      O << "%" << LowercaseString (RI.get(MO.getReg()).Name);
15377595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik    else
15477595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik      O << "%reg" << MO.getReg();
1558fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendling    break;
156dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
157cbb170d057aa6692b19f577b1e09a6c1c7a26969Rafael Espindola  case MachineOperand::MO_SignExtendedImmed:
158cbb170d057aa6692b19f577b1e09a6c1c7a26969Rafael Espindola  case MachineOperand::MO_UnextendedImmed:
1598fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendling    O << (int)MO.getImmedValue();
160dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
16177595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik  case MachineOperand::MO_MachineBasicBlock: {
16277595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik    MachineBasicBlock *MBBOp = MO.getMachineBasicBlock();
1638fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendling    O << ".LBB" << Mang->getValueName(MBBOp->getParent()->getFunction())
164dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      << "_" << MBBOp->getNumber () << "\t! "
16577595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik      << MBBOp->getBasicBlock ()->getName ();
16677595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik    return;
1678fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendling  }
1688fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendling  case MachineOperand::MO_PCRelativeDisp:
169dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    std::cerr << "Shouldn't use addPCDisp() when building SparcV8 MachineInstrs";
17077595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik    abort ();
17177595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik    return;
17236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case MachineOperand::MO_GlobalAddress:
173dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    O << Mang->getValueName(MO.getGlobal());
17436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    break;
17536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case MachineOperand::MO_ExternalSymbol:
17636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    O << MO.getSymbolName();
177dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
17836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  case MachineOperand::MO_ConstantPoolIndex:
17936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    O << PrivateGlobalPrefix << "CPI" << getFunctionNumber() << "_"
18036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines      << MO.getConstantPoolIndex();
181dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    break;
18236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  default:
18336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    O << "<unknown operand type>"; abort (); break;
18436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  }
185dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (CloseParen) O << ")";
18636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines}
18736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines
18836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid SparcV8AsmPrinter::printMemOperand(const MachineInstr *MI, int opNum) {
18936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  printOperand(MI, opNum);
19036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  MachineOperand::MachineOperandType OpTy = MI->getOperand(opNum+1).getType();
191dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
19236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines  if ((OpTy == MachineOperand::MO_VirtualRegister ||
19336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines       OpTy == MachineOperand::MO_MachineRegister) &&
1948fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendling      MI->getOperand(opNum+1).getReg() == V8::G0)
195cc48854d5d51a2d7557f1040a61f160ad86c9729Peter Collingbourne    return;   // don't print "+%g0"
196c13c9e5a9d288eac494a38f0710d34446167f940Rafael Espindola  if ((OpTy == MachineOperand::MO_SignExtendedImmed ||
19736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines       OpTy == MachineOperand::MO_UnextendedImmed) &&
198c13c9e5a9d288eac494a38f0710d34446167f940Rafael Espindola      MI->getOperand(opNum+1).getImmedValue() == 0)
199c13c9e5a9d288eac494a38f0710d34446167f940Rafael Espindola    return;   // don't print "+0"
200c13c9e5a9d288eac494a38f0710d34446167f940Rafael Espindola
201c13c9e5a9d288eac494a38f0710d34446167f940Rafael Espindola  O << "+";
202dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  if (OpTy == MachineOperand::MO_GlobalAddress ||
20377595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik      OpTy == MachineOperand::MO_ConstantPoolIndex) {
20477595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik    O << "%lo(";
205dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    printOperand(MI, opNum+1);
20677595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik    O << ")";
20707d5aef3057b2e403b20d683e7477c93fde67d99Reid Kleckner  } else {
208dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    printOperand(MI, opNum+1);
20977595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik  }
21077595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik}
21107d5aef3057b2e403b20d683e7477c93fde67d99Reid Kleckner
212dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
213235089bdaefabcef9e9cde28eb3b0d8937b12a0dShuxin Yangbool SparcV8AsmPrinter::doInitialization(Module &M) {
21477595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik  Mang = new Mangler(M);
21577595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik  return false; // success
21607d5aef3057b2e403b20d683e7477c93fde67d99Reid Kleckner}
217dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines
218235089bdaefabcef9e9cde28eb3b0d8937b12a0dShuxin Yangbool SparcV8AsmPrinter::doFinalization(Module &M) {
21977595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik  const TargetData &TD = TM.getTargetData();
22077595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik
221168f1428346f3d51304db0be64e1d5e4a09ca4c2Bill Wendling  // Print out module-level global variables here.
222dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines  for (Module::const_global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I)
223dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines    if (I->hasInitializer()) {   // External global require no code
224dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      O << "\n\n";
225dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      std::string name = Mang->getValueName(I);
226dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      Constant *C = I->getInitializer();
2272d643ef32891859ec73b6eea2959748f5ebc3af7Rafael Espindola      unsigned Size = TD.getTypeSize(C->getType());
2282d643ef32891859ec73b6eea2959748f5ebc3af7Rafael Espindola      unsigned Align = TD.getTypeAlignment(C->getType());
2298fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendling
230e9efea1194691580c74520aad48887d95fd0ce1bRafael Espindola      if (C->isNullValue() &&
231cbad58624090933cb8fb85587e03be613a481309Nick Kledzik          (I->hasLinkOnceLinkage() || I->hasInternalLinkage() ||
232cbad58624090933cb8fb85587e03be613a481309Nick Kledzik           I->hasWeakLinkage() /* FIXME: Verify correct */)) {
233168f1428346f3d51304db0be64e1d5e4a09ca4c2Bill Wendling        SwitchSection(".data", I);
2348fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendling        if (I->hasInternalLinkage())
235e9efea1194691580c74520aad48887d95fd0ce1bRafael Espindola          O << "\t.local " << name << "\n";
23698197e55c10176c3ef9100f7d852abbd2347225fRafael Espindola
23798197e55c10176c3ef9100f7d852abbd2347225fRafael Espindola        O << "\t.comm " << name << "," << TD.getTypeSize(C->getType())
2388fd3fcdba8be962aad1ed48bedbfddffc238c657Bill Wendling          << "," << (unsigned)TD.getTypeAlignment(C->getType());
239168f1428346f3d51304db0be64e1d5e4a09ca4c2Bill Wendling        O << "\t\t! ";
240dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        WriteAsOperand(O, I, true, true, &M);
24177595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik        O << "\n";
24277595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik      } else {
24307d5aef3057b2e403b20d683e7477c93fde67d99Reid Kleckner        switch (I->getLinkage()) {
2440e95b3aba9b2039ae3af617e681aacca2ff81f79Rafael Espindola        case GlobalValue::LinkOnceLinkage:
245dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        case GlobalValue::WeakLinkage:   // FIXME: Verify correct for weak.
246dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          // Nonnull linkonce -> weak
2470e95b3aba9b2039ae3af617e681aacca2ff81f79Rafael Espindola          O << "\t.weak " << name << "\n";
2480e95b3aba9b2039ae3af617e681aacca2ff81f79Rafael Espindola          SwitchSection("", I);
249dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          O << "\t.section\t\".llvm.linkonce.d." << name
25077595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik            << "\",\"aw\",@progbits\n";
25177595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik          break;
252168f1428346f3d51304db0be64e1d5e4a09ca4c2Bill Wendling
2530e95b3aba9b2039ae3af617e681aacca2ff81f79Rafael Espindola        case GlobalValue::AppendingLinkage:
254dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          // FIXME: appending linkage variables should go into a section of
255dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          // their name or something.  For now, just emit them as external.
2560e95b3aba9b2039ae3af617e681aacca2ff81f79Rafael Espindola        case GlobalValue::ExternalLinkage:
2570e95b3aba9b2039ae3af617e681aacca2ff81f79Rafael Espindola          // If external or appending, declare as a global symbol
258dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          O << "\t.globl " << name << "\n";
259dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          // FALL THROUGH
26077595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik        case GlobalValue::InternalLinkage:
26177595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik          if (C->isNullValue())
26207d5aef3057b2e403b20d683e7477c93fde67d99Reid Kleckner            SwitchSection(".bss", I);
2630e95b3aba9b2039ae3af617e681aacca2ff81f79Rafael Espindola          else
264dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines            SwitchSection(".data", I);
265dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          break;
2660e95b3aba9b2039ae3af617e681aacca2ff81f79Rafael Espindola        case GlobalValue::GhostLinkage:
2670e95b3aba9b2039ae3af617e681aacca2ff81f79Rafael Espindola          std::cerr << "Should not have any unmaterialized functions!\n";
268dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines          abort();
269dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        }
2706421a8815e14189121a5e20731fd005ea08793e1Rafael Espindola
2716421a8815e14189121a5e20731fd005ea08793e1Rafael Espindola        O << "\t.align " << Align << "\n";
272168f1428346f3d51304db0be64e1d5e4a09ca4c2Bill Wendling        O << "\t.type " << name << ",#object\n";
273dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines        O << "\t.size " << name << "," << Size << "\n";
274d44d4bf04b69fa7b003a0792a78ab132e40fe76fDuncan Sands        O << name << ":\t\t\t\t! ";
275        WriteAsOperand(O, I, true, true, &M);
276        O << " = ";
277        WriteAsOperand(O, C, false, false, &M);
278        O << "\n";
279        EmitGlobalConstant(C);
280      }
281    }
282
283  AsmPrinter::doFinalization(M);
284  return false; // success
285}
286