1cf78715cSZi Xuan Wu //===-- CSKYAsmPrinter.cpp - CSKY LLVM assembly writer --------------------===//
2cf78715cSZi Xuan Wu //
3cf78715cSZi Xuan Wu // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4cf78715cSZi Xuan Wu // See https://llvm.org/LICENSE.txt for license information.
5cf78715cSZi Xuan Wu // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6cf78715cSZi Xuan Wu //
7cf78715cSZi Xuan Wu //===----------------------------------------------------------------------===//
8cf78715cSZi Xuan Wu //
9cf78715cSZi Xuan Wu // This file contains a printer that converts from our internal representation
10cf78715cSZi Xuan Wu // of machine-dependent LLVM code to the CSKY assembly language.
11cf78715cSZi Xuan Wu //
12cf78715cSZi Xuan Wu //===----------------------------------------------------------------------===//
13cf78715cSZi Xuan Wu #include "CSKYAsmPrinter.h"
14cf78715cSZi Xuan Wu #include "CSKY.h"
158ddc8169SZi Xuan Wu #include "CSKYConstantPoolValue.h"
16cf78715cSZi Xuan Wu #include "CSKYTargetMachine.h"
17cf78715cSZi Xuan Wu #include "MCTargetDesc/CSKYInstPrinter.h"
18cf78715cSZi Xuan Wu #include "MCTargetDesc/CSKYMCExpr.h"
1932977589SZi Xuan Wu #include "MCTargetDesc/CSKYTargetStreamer.h"
20cf78715cSZi Xuan Wu #include "TargetInfo/CSKYTargetInfo.h"
21cf78715cSZi Xuan Wu #include "llvm/ADT/Statistic.h"
22cf78715cSZi Xuan Wu #include "llvm/CodeGen/AsmPrinter.h"
23cf78715cSZi Xuan Wu #include "llvm/CodeGen/MachineConstantPool.h"
24989f1c72Sserge-sans-paille #include "llvm/CodeGen/MachineFrameInfo.h"
25cf78715cSZi Xuan Wu #include "llvm/IR/DataLayout.h"
26cf78715cSZi Xuan Wu #include "llvm/MC/MCAsmInfo.h"
27cf78715cSZi Xuan Wu #include "llvm/MC/MCContext.h"
28cf78715cSZi Xuan Wu #include "llvm/MC/MCInstBuilder.h"
29cf78715cSZi Xuan Wu #include "llvm/MC/MCStreamer.h"
30cf78715cSZi Xuan Wu #include "llvm/MC/TargetRegistry.h"
31cf78715cSZi Xuan Wu 
32cf78715cSZi Xuan Wu using namespace llvm;
33cf78715cSZi Xuan Wu 
34cf78715cSZi Xuan Wu #define DEBUG_TYPE "csky-asm-printer"
35cf78715cSZi Xuan Wu 
36bdd7c53dSZi Xuan Wu STATISTIC(CSKYNumInstrsCompressed,
37bdd7c53dSZi Xuan Wu           "Number of C-SKY Compressed instructions emitted");
38bdd7c53dSZi Xuan Wu 
CSKYAsmPrinter(llvm::TargetMachine & TM,std::unique_ptr<llvm::MCStreamer> Streamer)39cf78715cSZi Xuan Wu CSKYAsmPrinter::CSKYAsmPrinter(llvm::TargetMachine &TM,
40cf78715cSZi Xuan Wu                                std::unique_ptr<llvm::MCStreamer> Streamer)
41cf78715cSZi Xuan Wu     : AsmPrinter(TM, std::move(Streamer)), MCInstLowering(OutContext, *this) {}
42cf78715cSZi Xuan Wu 
runOnMachineFunction(MachineFunction & MF)43cf78715cSZi Xuan Wu bool CSKYAsmPrinter::runOnMachineFunction(MachineFunction &MF) {
44065e0324SZi Xuan Wu   MCP = MF.getConstantPool();
4532977589SZi Xuan Wu   TII = MF.getSubtarget().getInstrInfo();
4632977589SZi Xuan Wu 
4732977589SZi Xuan Wu   // Set the current MCSubtargetInfo to a copy which has the correct
4832977589SZi Xuan Wu   // feature bits for the current MachineFunction
4932977589SZi Xuan Wu   MCSubtargetInfo &NewSTI =
5032977589SZi Xuan Wu       OutStreamer->getContext().getSubtargetCopy(*TM.getMCSubtargetInfo());
5132977589SZi Xuan Wu   NewSTI.setFeatureBits(MF.getSubtarget().getFeatureBits());
5232977589SZi Xuan Wu   Subtarget = &NewSTI;
5332977589SZi Xuan Wu 
54cf78715cSZi Xuan Wu   return AsmPrinter::runOnMachineFunction(MF);
55cf78715cSZi Xuan Wu }
56cf78715cSZi Xuan Wu 
57bdd7c53dSZi Xuan Wu #define GEN_COMPRESS_INSTR
58bdd7c53dSZi Xuan Wu #include "CSKYGenCompressInstEmitter.inc"
EmitToStreamer(MCStreamer & S,const MCInst & Inst)59bdd7c53dSZi Xuan Wu void CSKYAsmPrinter::EmitToStreamer(MCStreamer &S, const MCInst &Inst) {
60bdd7c53dSZi Xuan Wu   MCInst CInst;
61bdd7c53dSZi Xuan Wu   bool Res = compressInst(CInst, Inst, *Subtarget, OutStreamer->getContext());
62bdd7c53dSZi Xuan Wu   if (Res)
63bdd7c53dSZi Xuan Wu     ++CSKYNumInstrsCompressed;
64bdd7c53dSZi Xuan Wu   AsmPrinter::EmitToStreamer(*OutStreamer, Res ? CInst : Inst);
65bdd7c53dSZi Xuan Wu }
66bdd7c53dSZi Xuan Wu 
67cf78715cSZi Xuan Wu // Simple pseudo-instructions have their lowering (with expansion to real
68cf78715cSZi Xuan Wu // instructions) auto-generated.
69cf78715cSZi Xuan Wu #include "CSKYGenMCPseudoLowering.inc"
70cf78715cSZi Xuan Wu 
expandTLSLA(const MachineInstr * MI)7182bb8a58SZi Xuan Wu void CSKYAsmPrinter::expandTLSLA(const MachineInstr *MI) {
7282bb8a58SZi Xuan Wu   DebugLoc DL = MI->getDebugLoc();
7382bb8a58SZi Xuan Wu 
7482bb8a58SZi Xuan Wu   MCSymbol *PCLabel = OutContext.getOrCreateSymbol(
7582bb8a58SZi Xuan Wu       Twine(MAI->getPrivateGlobalPrefix()) + "PC" + Twine(getFunctionNumber()) +
7682bb8a58SZi Xuan Wu       "_" + Twine(MI->getOperand(3).getImm()));
7782bb8a58SZi Xuan Wu 
7882bb8a58SZi Xuan Wu   OutStreamer->emitLabel(PCLabel);
7982bb8a58SZi Xuan Wu 
8082bb8a58SZi Xuan Wu   auto Instr = BuildMI(*MF, DL, TII->get(CSKY::LRW32))
8182bb8a58SZi Xuan Wu                    .add(MI->getOperand(0))
8282bb8a58SZi Xuan Wu                    .add(MI->getOperand(2));
8382bb8a58SZi Xuan Wu   MCInst LRWInst;
8482bb8a58SZi Xuan Wu   MCInstLowering.Lower(Instr, LRWInst);
8582bb8a58SZi Xuan Wu   EmitToStreamer(*OutStreamer, LRWInst);
8682bb8a58SZi Xuan Wu 
8782bb8a58SZi Xuan Wu   Instr = BuildMI(*MF, DL, TII->get(CSKY::GRS32))
8882bb8a58SZi Xuan Wu               .add(MI->getOperand(1))
8982bb8a58SZi Xuan Wu               .addSym(PCLabel);
9082bb8a58SZi Xuan Wu   MCInst GRSInst;
9182bb8a58SZi Xuan Wu   MCInstLowering.Lower(Instr, GRSInst);
9282bb8a58SZi Xuan Wu   EmitToStreamer(*OutStreamer, GRSInst);
9382bb8a58SZi Xuan Wu   return;
9482bb8a58SZi Xuan Wu }
9582bb8a58SZi Xuan Wu 
emitCustomConstantPool(const MachineInstr * MI)96065e0324SZi Xuan Wu void CSKYAsmPrinter::emitCustomConstantPool(const MachineInstr *MI) {
97065e0324SZi Xuan Wu 
98065e0324SZi Xuan Wu   // This instruction represents a floating constant pool in the function.
99065e0324SZi Xuan Wu   // The first operand is the ID# for this instruction, the second is the
100065e0324SZi Xuan Wu   // index into the MachineConstantPool that this is, the third is the size
101065e0324SZi Xuan Wu   // in bytes of this constant pool entry.
102065e0324SZi Xuan Wu   // The required alignment is specified on the basic block holding this MI.
103065e0324SZi Xuan Wu   unsigned LabelId = (unsigned)MI->getOperand(0).getImm();
104065e0324SZi Xuan Wu   unsigned CPIdx = (unsigned)MI->getOperand(1).getIndex();
105065e0324SZi Xuan Wu 
106065e0324SZi Xuan Wu   // If this is the first entry of the pool, mark it.
107065e0324SZi Xuan Wu   if (!InConstantPool) {
108065e0324SZi Xuan Wu     OutStreamer->emitValueToAlignment(4);
109065e0324SZi Xuan Wu     InConstantPool = true;
110065e0324SZi Xuan Wu   }
111065e0324SZi Xuan Wu 
112065e0324SZi Xuan Wu   OutStreamer->emitLabel(GetCPISymbol(LabelId));
113065e0324SZi Xuan Wu 
114065e0324SZi Xuan Wu   const MachineConstantPoolEntry &MCPE = MCP->getConstants()[CPIdx];
115065e0324SZi Xuan Wu   if (MCPE.isMachineConstantPoolEntry())
116065e0324SZi Xuan Wu     emitMachineConstantPoolValue(MCPE.Val.MachineCPVal);
117065e0324SZi Xuan Wu   else
118065e0324SZi Xuan Wu     emitGlobalConstant(MF->getDataLayout(), MCPE.Val.ConstVal);
119065e0324SZi Xuan Wu   return;
120065e0324SZi Xuan Wu }
121065e0324SZi Xuan Wu 
emitFunctionBodyEnd()122065e0324SZi Xuan Wu void CSKYAsmPrinter::emitFunctionBodyEnd() {
123065e0324SZi Xuan Wu   // Make sure to terminate any constant pools that were at the end
124065e0324SZi Xuan Wu   // of the function.
125065e0324SZi Xuan Wu   if (!InConstantPool)
126065e0324SZi Xuan Wu     return;
127065e0324SZi Xuan Wu   InConstantPool = false;
128065e0324SZi Xuan Wu }
129065e0324SZi Xuan Wu 
emitStartOfAsmFile(Module & M)13032977589SZi Xuan Wu void CSKYAsmPrinter::emitStartOfAsmFile(Module &M) {
13132977589SZi Xuan Wu   if (TM.getTargetTriple().isOSBinFormatELF())
13232977589SZi Xuan Wu     emitAttributes();
13332977589SZi Xuan Wu }
13432977589SZi Xuan Wu 
emitEndOfAsmFile(Module & M)13532977589SZi Xuan Wu void CSKYAsmPrinter::emitEndOfAsmFile(Module &M) {
13632977589SZi Xuan Wu   CSKYTargetStreamer &CTS =
13732977589SZi Xuan Wu       static_cast<CSKYTargetStreamer &>(*OutStreamer->getTargetStreamer());
13832977589SZi Xuan Wu 
13932977589SZi Xuan Wu   if (TM.getTargetTriple().isOSBinFormatELF())
14032977589SZi Xuan Wu     CTS.finishAttributeSection();
14132977589SZi Xuan Wu }
14232977589SZi Xuan Wu 
emitInstruction(const MachineInstr * MI)143cf78715cSZi Xuan Wu void CSKYAsmPrinter::emitInstruction(const MachineInstr *MI) {
144*3e0bf1c7SDavid Green   CSKY_MC::verifyInstructionPredicates(MI->getOpcode(),
145*3e0bf1c7SDavid Green                                        getSubtargetInfo().getFeatureBits());
146*3e0bf1c7SDavid Green 
147cf78715cSZi Xuan Wu   // Do any auto-generated pseudo lowerings.
148cf78715cSZi Xuan Wu   if (emitPseudoExpansionLowering(*OutStreamer, MI))
149cf78715cSZi Xuan Wu     return;
150cf78715cSZi Xuan Wu 
151065e0324SZi Xuan Wu   // If we just ended a constant pool, mark it as such.
152065e0324SZi Xuan Wu   if (InConstantPool && MI->getOpcode() != CSKY::CONSTPOOL_ENTRY) {
153065e0324SZi Xuan Wu     InConstantPool = false;
154065e0324SZi Xuan Wu   }
155065e0324SZi Xuan Wu 
15682bb8a58SZi Xuan Wu   if (MI->getOpcode() == CSKY::PseudoTLSLA32)
15782bb8a58SZi Xuan Wu     return expandTLSLA(MI);
15882bb8a58SZi Xuan Wu 
159065e0324SZi Xuan Wu   if (MI->getOpcode() == CSKY::CONSTPOOL_ENTRY)
160065e0324SZi Xuan Wu     return emitCustomConstantPool(MI);
161065e0324SZi Xuan Wu 
162cf78715cSZi Xuan Wu   MCInst TmpInst;
163cf78715cSZi Xuan Wu   MCInstLowering.Lower(MI, TmpInst);
164cf78715cSZi Xuan Wu   EmitToStreamer(*OutStreamer, TmpInst);
165cf78715cSZi Xuan Wu }
166cf78715cSZi Xuan Wu 
1678ddc8169SZi Xuan Wu // Convert a CSKY-specific constant pool modifier into the associated
1688ddc8169SZi Xuan Wu // MCSymbolRefExpr variant kind.
1698ddc8169SZi Xuan Wu static CSKYMCExpr::VariantKind
getModifierVariantKind(CSKYCP::CSKYCPModifier Modifier)1708ddc8169SZi Xuan Wu getModifierVariantKind(CSKYCP::CSKYCPModifier Modifier) {
1718ddc8169SZi Xuan Wu   switch (Modifier) {
1728ddc8169SZi Xuan Wu   case CSKYCP::NO_MOD:
1738ddc8169SZi Xuan Wu     return CSKYMCExpr::VK_CSKY_None;
1748ddc8169SZi Xuan Wu   case CSKYCP::ADDR:
1758ddc8169SZi Xuan Wu     return CSKYMCExpr::VK_CSKY_ADDR;
1768ddc8169SZi Xuan Wu   case CSKYCP::GOT:
1778ddc8169SZi Xuan Wu     return CSKYMCExpr::VK_CSKY_GOT;
1788ddc8169SZi Xuan Wu   case CSKYCP::GOTOFF:
1798ddc8169SZi Xuan Wu     return CSKYMCExpr::VK_CSKY_GOTOFF;
1808ddc8169SZi Xuan Wu   case CSKYCP::PLT:
1818ddc8169SZi Xuan Wu     return CSKYMCExpr::VK_CSKY_PLT;
1828ddc8169SZi Xuan Wu   case CSKYCP::TLSGD:
1838ddc8169SZi Xuan Wu     return CSKYMCExpr::VK_CSKY_TLSGD;
1848ddc8169SZi Xuan Wu   case CSKYCP::TLSLE:
1858ddc8169SZi Xuan Wu     return CSKYMCExpr::VK_CSKY_TLSLE;
1868ddc8169SZi Xuan Wu   case CSKYCP::TLSIE:
1878ddc8169SZi Xuan Wu     return CSKYMCExpr::VK_CSKY_TLSIE;
1888ddc8169SZi Xuan Wu   }
1898ddc8169SZi Xuan Wu   llvm_unreachable("Invalid CSKYCPModifier!");
1908ddc8169SZi Xuan Wu }
1918ddc8169SZi Xuan Wu 
emitMachineConstantPoolValue(MachineConstantPoolValue * MCPV)1928ddc8169SZi Xuan Wu void CSKYAsmPrinter::emitMachineConstantPoolValue(
1938ddc8169SZi Xuan Wu     MachineConstantPoolValue *MCPV) {
1948ddc8169SZi Xuan Wu   int Size = getDataLayout().getTypeAllocSize(MCPV->getType());
1958ddc8169SZi Xuan Wu   CSKYConstantPoolValue *CCPV = static_cast<CSKYConstantPoolValue *>(MCPV);
1968ddc8169SZi Xuan Wu   MCSymbol *MCSym;
1978ddc8169SZi Xuan Wu 
1988ddc8169SZi Xuan Wu   if (CCPV->isBlockAddress()) {
1998ddc8169SZi Xuan Wu     const BlockAddress *BA =
2008ddc8169SZi Xuan Wu         cast<CSKYConstantPoolConstant>(CCPV)->getBlockAddress();
2018ddc8169SZi Xuan Wu     MCSym = GetBlockAddressSymbol(BA);
2028ddc8169SZi Xuan Wu   } else if (CCPV->isGlobalValue()) {
2038ddc8169SZi Xuan Wu     const GlobalValue *GV = cast<CSKYConstantPoolConstant>(CCPV)->getGV();
2048ddc8169SZi Xuan Wu     MCSym = getSymbol(GV);
2058ddc8169SZi Xuan Wu   } else if (CCPV->isMachineBasicBlock()) {
2068ddc8169SZi Xuan Wu     const MachineBasicBlock *MBB = cast<CSKYConstantPoolMBB>(CCPV)->getMBB();
2078ddc8169SZi Xuan Wu     MCSym = MBB->getSymbol();
2088ddc8169SZi Xuan Wu   } else if (CCPV->isJT()) {
2098ddc8169SZi Xuan Wu     signed JTI = cast<CSKYConstantPoolJT>(CCPV)->getJTI();
2108ddc8169SZi Xuan Wu     MCSym = GetJTISymbol(JTI);
2118ddc8169SZi Xuan Wu   } else {
2128ddc8169SZi Xuan Wu     assert(CCPV->isExtSymbol() && "unrecognized constant pool value");
2138ddc8169SZi Xuan Wu     StringRef Sym = cast<CSKYConstantPoolSymbol>(CCPV)->getSymbol();
2148ddc8169SZi Xuan Wu     MCSym = GetExternalSymbolSymbol(Sym);
2158ddc8169SZi Xuan Wu   }
2168ddc8169SZi Xuan Wu   // Create an MCSymbol for the reference.
2178ddc8169SZi Xuan Wu   const MCExpr *Expr =
2188ddc8169SZi Xuan Wu       MCSymbolRefExpr::create(MCSym, MCSymbolRefExpr::VK_None, OutContext);
2198ddc8169SZi Xuan Wu 
2208ddc8169SZi Xuan Wu   if (CCPV->getPCAdjustment()) {
2218ddc8169SZi Xuan Wu 
2228ddc8169SZi Xuan Wu     MCSymbol *PCLabel = OutContext.getOrCreateSymbol(
2238ddc8169SZi Xuan Wu         Twine(MAI->getPrivateGlobalPrefix()) + "PC" +
2248ddc8169SZi Xuan Wu         Twine(getFunctionNumber()) + "_" + Twine(CCPV->getLabelID()));
2258ddc8169SZi Xuan Wu 
2268ddc8169SZi Xuan Wu     const MCExpr *PCRelExpr = MCSymbolRefExpr::create(PCLabel, OutContext);
2278ddc8169SZi Xuan Wu     if (CCPV->mustAddCurrentAddress()) {
2288ddc8169SZi Xuan Wu       // We want "(<expr> - .)", but MC doesn't have a concept of the '.'
2298ddc8169SZi Xuan Wu       // label, so just emit a local label end reference that instead.
2308ddc8169SZi Xuan Wu       MCSymbol *DotSym = OutContext.createTempSymbol();
2318ddc8169SZi Xuan Wu       OutStreamer->emitLabel(DotSym);
2328ddc8169SZi Xuan Wu       const MCExpr *DotExpr = MCSymbolRefExpr::create(DotSym, OutContext);
2338ddc8169SZi Xuan Wu       PCRelExpr = MCBinaryExpr::createSub(PCRelExpr, DotExpr, OutContext);
2348ddc8169SZi Xuan Wu     }
2358ddc8169SZi Xuan Wu     Expr = MCBinaryExpr::createSub(Expr, PCRelExpr, OutContext);
2368ddc8169SZi Xuan Wu   }
2378ddc8169SZi Xuan Wu 
2388ddc8169SZi Xuan Wu   // Create an MCSymbol for the reference.
2398ddc8169SZi Xuan Wu   Expr = CSKYMCExpr::create(Expr, getModifierVariantKind(CCPV->getModifier()),
2408ddc8169SZi Xuan Wu                             OutContext);
2418ddc8169SZi Xuan Wu 
2428ddc8169SZi Xuan Wu   OutStreamer->emitValue(Expr, Size);
2438ddc8169SZi Xuan Wu }
2448ddc8169SZi Xuan Wu 
emitAttributes()24532977589SZi Xuan Wu void CSKYAsmPrinter::emitAttributes() {
24632977589SZi Xuan Wu   CSKYTargetStreamer &CTS =
24732977589SZi Xuan Wu       static_cast<CSKYTargetStreamer &>(*OutStreamer->getTargetStreamer());
24832977589SZi Xuan Wu 
24932977589SZi Xuan Wu   const Triple &TT = TM.getTargetTriple();
25032977589SZi Xuan Wu   StringRef CPU = TM.getTargetCPU();
25132977589SZi Xuan Wu   StringRef FS = TM.getTargetFeatureString();
25232977589SZi Xuan Wu   const CSKYTargetMachine &CTM = static_cast<const CSKYTargetMachine &>(TM);
25332977589SZi Xuan Wu   /* TuneCPU doesn't impact emission of ELF attributes, ELF attributes only
25432977589SZi Xuan Wu      care about arch related features, so we can set TuneCPU as CPU.  */
25532977589SZi Xuan Wu   const CSKYSubtarget STI(TT, CPU, /*TuneCPU=*/CPU, FS, CTM);
25632977589SZi Xuan Wu 
25732977589SZi Xuan Wu   CTS.emitTargetAttributes(STI);
25832977589SZi Xuan Wu }
25932977589SZi Xuan Wu 
PrintAsmOperand(const MachineInstr * MI,unsigned OpNo,const char * ExtraCode,raw_ostream & OS)260a190fcdfSZi Xuan Wu bool CSKYAsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
261a190fcdfSZi Xuan Wu                                      const char *ExtraCode, raw_ostream &OS) {
262a190fcdfSZi Xuan Wu   // First try the generic code, which knows about modifiers like 'c' and 'n'.
263a190fcdfSZi Xuan Wu   if (!AsmPrinter::PrintAsmOperand(MI, OpNo, ExtraCode, OS))
264a190fcdfSZi Xuan Wu     return false;
265a190fcdfSZi Xuan Wu 
266a190fcdfSZi Xuan Wu   const MachineOperand &MO = MI->getOperand(OpNo);
267a190fcdfSZi Xuan Wu   if (ExtraCode && ExtraCode[0]) {
268a190fcdfSZi Xuan Wu     if (ExtraCode[1] != 0)
269a190fcdfSZi Xuan Wu       return true; // Unknown modifier.
270a190fcdfSZi Xuan Wu 
271a190fcdfSZi Xuan Wu     switch (ExtraCode[0]) {
272a190fcdfSZi Xuan Wu     default:
273a190fcdfSZi Xuan Wu       return true; // Unknown modifier.
274a190fcdfSZi Xuan Wu     case 'R':
275a190fcdfSZi Xuan Wu       if (MO.getType() == MachineOperand::MO_Register) {
276a190fcdfSZi Xuan Wu         OS << CSKYInstPrinter::getRegisterName(MO.getReg() + 1);
277a190fcdfSZi Xuan Wu         return false;
278a190fcdfSZi Xuan Wu       }
279a190fcdfSZi Xuan Wu     }
280a190fcdfSZi Xuan Wu   }
281a190fcdfSZi Xuan Wu 
282a190fcdfSZi Xuan Wu   switch (MO.getType()) {
283a190fcdfSZi Xuan Wu   case MachineOperand::MO_Immediate:
284a190fcdfSZi Xuan Wu     OS << MO.getImm();
285a190fcdfSZi Xuan Wu     return false;
286a190fcdfSZi Xuan Wu   case MachineOperand::MO_Register:
287a190fcdfSZi Xuan Wu     if (MO.getReg() == CSKY::C)
288a190fcdfSZi Xuan Wu       return false;
289a190fcdfSZi Xuan Wu     OS << CSKYInstPrinter::getRegisterName(MO.getReg());
290a190fcdfSZi Xuan Wu     return false;
291a190fcdfSZi Xuan Wu   case MachineOperand::MO_GlobalAddress:
292a190fcdfSZi Xuan Wu     PrintSymbolOperand(MO, OS);
293a190fcdfSZi Xuan Wu     return false;
294a190fcdfSZi Xuan Wu   case MachineOperand::MO_BlockAddress: {
295a190fcdfSZi Xuan Wu     MCSymbol *Sym = GetBlockAddressSymbol(MO.getBlockAddress());
296a190fcdfSZi Xuan Wu     Sym->print(OS, MAI);
297a190fcdfSZi Xuan Wu     return false;
298a190fcdfSZi Xuan Wu   }
299a190fcdfSZi Xuan Wu   default:
300a190fcdfSZi Xuan Wu     break;
301a190fcdfSZi Xuan Wu   }
302a190fcdfSZi Xuan Wu 
303a190fcdfSZi Xuan Wu   return true;
304a190fcdfSZi Xuan Wu }
305a190fcdfSZi Xuan Wu 
PrintAsmMemoryOperand(const MachineInstr * MI,unsigned OpNo,const char * ExtraCode,raw_ostream & OS)306a190fcdfSZi Xuan Wu bool CSKYAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
307a190fcdfSZi Xuan Wu                                            unsigned OpNo, const char *ExtraCode,
308a190fcdfSZi Xuan Wu                                            raw_ostream &OS) {
309a190fcdfSZi Xuan Wu   if (!ExtraCode) {
310a190fcdfSZi Xuan Wu     const MachineOperand &MO = MI->getOperand(OpNo);
311a190fcdfSZi Xuan Wu     // For now, we only support register memory operands in registers and
312a190fcdfSZi Xuan Wu     // assume there is no addend
313a190fcdfSZi Xuan Wu     if (!MO.isReg())
314a190fcdfSZi Xuan Wu       return true;
315a190fcdfSZi Xuan Wu 
316a190fcdfSZi Xuan Wu     OS << "(" << CSKYInstPrinter::getRegisterName(MO.getReg()) << ", 0)";
317a190fcdfSZi Xuan Wu     return false;
318a190fcdfSZi Xuan Wu   }
319a190fcdfSZi Xuan Wu 
320a190fcdfSZi Xuan Wu   return AsmPrinter::PrintAsmMemoryOperand(MI, OpNo, ExtraCode, OS);
321a190fcdfSZi Xuan Wu }
322a190fcdfSZi Xuan Wu 
LLVMInitializeCSKYAsmPrinter()323cf78715cSZi Xuan Wu extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeCSKYAsmPrinter() {
324cf78715cSZi Xuan Wu   RegisterAsmPrinter<CSKYAsmPrinter> X(getTheCSKYTarget());
325cf78715cSZi Xuan Wu }
326