blob: ed9844e1bee47b8c56c6067fbbb3a59d6a8bd0ea [file] [log] [blame]
Jakob Stoklund Olesend9509412009-08-02 17:32:10 +00001//===-- BlackfinAsmPrinter.cpp - Blackfin LLVM assembly writer ------------===//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file contains a printer that converts from our internal representation
11// of machine-dependent LLVM code to GAS-format BLACKFIN assembly language.
12//
13//===----------------------------------------------------------------------===//
14
15#define DEBUG_TYPE "asm-printer"
16#include "Blackfin.h"
17#include "BlackfinInstrInfo.h"
18#include "llvm/Constants.h"
19#include "llvm/DerivedTypes.h"
20#include "llvm/Module.h"
21#include "llvm/CodeGen/AsmPrinter.h"
Jakob Stoklund Olesend9509412009-08-02 17:32:10 +000022#include "llvm/CodeGen/MachineFunctionPass.h"
23#include "llvm/CodeGen/MachineConstantPool.h"
24#include "llvm/CodeGen/MachineInstr.h"
Chris Lattner6c2f9e12009-08-19 05:49:37 +000025#include "llvm/MC/MCStreamer.h"
Chris Lattneraf76e592009-08-22 20:48:53 +000026#include "llvm/MC/MCAsmInfo.h"
Chris Lattner13b1e922010-01-13 08:04:24 +000027#include "llvm/MC/MCContext.h"
Chris Lattner325d3dc2009-09-13 17:14:04 +000028#include "llvm/MC/MCSymbol.h"
Chris Lattnerd62f1b42010-03-12 21:19:23 +000029#include "llvm/Target/Mangler.h"
Jakob Stoklund Olesend9509412009-08-02 17:32:10 +000030#include "llvm/Target/TargetData.h"
31#include "llvm/Target/TargetLoweringObjectFile.h"
Chris Lattner48130352010-01-13 06:38:18 +000032#include "llvm/ADT/SmallString.h"
Chris Lattner8f9b0f62009-11-07 09:20:54 +000033#include "llvm/Support/ErrorHandling.h"
Evan Cheng3e74d6f2011-08-24 18:08:43 +000034#include "llvm/Support/TargetRegistry.h"
Chris Lattnerb23569a2010-04-04 08:18:47 +000035#include "llvm/Support/raw_ostream.h"
Jakob Stoklund Olesend9509412009-08-02 17:32:10 +000036using namespace llvm;
37
Jakob Stoklund Olesend9509412009-08-02 17:32:10 +000038namespace {
Nick Lewycky6726b6d2009-10-25 06:33:48 +000039 class BlackfinAsmPrinter : public AsmPrinter {
Jakob Stoklund Olesend9509412009-08-02 17:32:10 +000040 public:
Chris Lattnerb23569a2010-04-04 08:18:47 +000041 BlackfinAsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
42 : AsmPrinter(TM, Streamer) {}
Jakob Stoklund Olesend9509412009-08-02 17:32:10 +000043
44 virtual const char *getPassName() const {
45 return "Blackfin Assembly Printer";
46 }
47
Chris Lattner35c33bd2010-04-04 04:47:45 +000048 void printOperand(const MachineInstr *MI, int opNum, raw_ostream &O);
49 void printMemoryOperand(const MachineInstr *MI, int opNum, raw_ostream &O);
50 void printInstruction(const MachineInstr *MI, raw_ostream &O);// autogen'd.
Chris Lattnerd95148f2009-09-13 20:19:22 +000051 static const char *getRegisterName(unsigned RegNo);
Chris Lattner05af2612009-09-13 20:08:00 +000052
Chris Lattnerd1ff72b2010-02-03 01:09:55 +000053 void EmitInstruction(const MachineInstr *MI) {
Chris Lattner7ad07c42010-04-04 06:12:20 +000054 SmallString<128> Str;
55 raw_svector_ostream OS(Str);
56 printInstruction(MI, OS);
57 OutStreamer.EmitRawText(OS.str());
Chris Lattnerd1ff72b2010-02-03 01:09:55 +000058 }
Jakob Stoklund Olesend9509412009-08-02 17:32:10 +000059 bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
Chris Lattnerc75c0282010-04-04 05:29:35 +000060 unsigned AsmVariant, const char *ExtraCode,
61 raw_ostream &O);
Jakob Stoklund Olesend9509412009-08-02 17:32:10 +000062 bool PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
Chris Lattnerc75c0282010-04-04 05:29:35 +000063 unsigned AsmVariant, const char *ExtraCode,
64 raw_ostream &O);
Jakob Stoklund Olesend9509412009-08-02 17:32:10 +000065 };
66} // end of anonymous namespace
67
68#include "BlackfinGenAsmWriter.inc"
69
70extern "C" void LLVMInitializeBlackfinAsmPrinter() {
71 RegisterAsmPrinter<BlackfinAsmPrinter> X(TheBlackfinTarget);
72}
73
Chris Lattner35c33bd2010-04-04 04:47:45 +000074void BlackfinAsmPrinter::printOperand(const MachineInstr *MI, int opNum,
75 raw_ostream &O) {
76 const MachineOperand &MO = MI->getOperand(opNum);
Jakob Stoklund Olesend9509412009-08-02 17:32:10 +000077 switch (MO.getType()) {
78 case MachineOperand::MO_Register:
Jakob Stoklund Olesenea1c9b72009-08-03 19:32:30 +000079 assert(TargetRegisterInfo::isPhysicalRegister(MO.getReg()) &&
80 "Virtual registers should be already mapped!");
Chris Lattner762ccea2009-09-13 20:31:40 +000081 O << getRegisterName(MO.getReg());
Jakob Stoklund Olesend9509412009-08-02 17:32:10 +000082 break;
83
84 case MachineOperand::MO_Immediate:
85 O << MO.getImm();
86 break;
87 case MachineOperand::MO_MachineBasicBlock:
Chris Lattner1b2eb0e2010-03-13 21:04:28 +000088 O << *MO.getMBB()->getSymbol();
Jakob Stoklund Olesend9509412009-08-02 17:32:10 +000089 return;
90 case MachineOperand::MO_GlobalAddress:
Chris Lattnerd62f1b42010-03-12 21:19:23 +000091 O << *Mang->getSymbol(MO.getGlobal());
Chris Lattner0c08d092010-04-03 22:28:33 +000092 printOffset(MO.getOffset(), O);
Jakob Stoklund Olesend9509412009-08-02 17:32:10 +000093 break;
Chris Lattner6b04ede2010-01-15 23:18:17 +000094 case MachineOperand::MO_ExternalSymbol:
Chris Lattner10b318b2010-01-17 21:43:43 +000095 O << *GetExternalSymbolSymbol(MO.getSymbolName());
Jakob Stoklund Olesend9509412009-08-02 17:32:10 +000096 break;
97 case MachineOperand::MO_ConstantPoolIndex:
Chris Lattner33adcfb2009-08-22 21:43:10 +000098 O << MAI->getPrivateGlobalPrefix() << "CPI" << getFunctionNumber() << "_"
Jakob Stoklund Olesend9509412009-08-02 17:32:10 +000099 << MO.getIndex();
100 break;
101 case MachineOperand::MO_JumpTableIndex:
Chris Lattner33adcfb2009-08-22 21:43:10 +0000102 O << MAI->getPrivateGlobalPrefix() << "JTI" << getFunctionNumber()
Jakob Stoklund Olesend9509412009-08-02 17:32:10 +0000103 << '_' << MO.getIndex();
104 break;
105 default:
106 llvm_unreachable("<unknown operand type>");
107 break;
108 }
109}
110
Chris Lattner35c33bd2010-04-04 04:47:45 +0000111void BlackfinAsmPrinter::printMemoryOperand(const MachineInstr *MI, int opNum,
112 raw_ostream &O) {
113 printOperand(MI, opNum, O);
Jakob Stoklund Olesend9509412009-08-02 17:32:10 +0000114
115 if (MI->getOperand(opNum+1).isImm() && MI->getOperand(opNum+1).getImm() == 0)
116 return;
117
118 O << " + ";
Chris Lattner35c33bd2010-04-04 04:47:45 +0000119 printOperand(MI, opNum+1, O);
Jakob Stoklund Olesend9509412009-08-02 17:32:10 +0000120}
121
122/// PrintAsmOperand - Print out an operand for an inline asm expression.
123///
124bool BlackfinAsmPrinter::PrintAsmOperand(const MachineInstr *MI,
Chris Lattnerc75c0282010-04-04 05:29:35 +0000125 unsigned OpNo, unsigned AsmVariant,
126 const char *ExtraCode,
127 raw_ostream &O) {
Jakob Stoklund Olesend9509412009-08-02 17:32:10 +0000128 if (ExtraCode && ExtraCode[0]) {
129 if (ExtraCode[1] != 0) return true; // Unknown modifier.
130
131 switch (ExtraCode[0]) {
132 default: return true; // Unknown modifier.
133 case 'r':
134 break;
135 }
136 }
137
Chris Lattner35c33bd2010-04-04 04:47:45 +0000138 printOperand(MI, OpNo, O);
Jakob Stoklund Olesend9509412009-08-02 17:32:10 +0000139
140 return false;
141}
142
143bool BlackfinAsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
144 unsigned OpNo,
145 unsigned AsmVariant,
Chris Lattnerc75c0282010-04-04 05:29:35 +0000146 const char *ExtraCode,
147 raw_ostream &O) {
Jakob Stoklund Olesend9509412009-08-02 17:32:10 +0000148 if (ExtraCode && ExtraCode[0])
149 return true; // Unknown modifier
150
151 O << '[';
Chris Lattner35c33bd2010-04-04 04:47:45 +0000152 printOperand(MI, OpNo, O);
Jakob Stoklund Olesend9509412009-08-02 17:32:10 +0000153 O << ']';
154
155 return false;
156}