LLVM API Documentation

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MSP430AsmPrinter.cpp
Go to the documentation of this file.
1 //===-- MSP430AsmPrinter.cpp - MSP430 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 the MSP430 assembly language.
12 //
13 //===----------------------------------------------------------------------===//
14 
15 #define DEBUG_TYPE "asm-printer"
16 #include "MSP430.h"
18 #include "MSP430InstrInfo.h"
19 #include "MSP430MCInstLower.h"
20 #include "MSP430TargetMachine.h"
21 #include "llvm/Assembly/Writer.h"
27 #include "llvm/IR/Constants.h"
28 #include "llvm/IR/DerivedTypes.h"
29 #include "llvm/IR/Module.h"
30 #include "llvm/MC/MCAsmInfo.h"
31 #include "llvm/MC/MCInst.h"
32 #include "llvm/MC/MCStreamer.h"
33 #include "llvm/MC/MCSymbol.h"
36 #include "llvm/Target/Mangler.h"
37 using namespace llvm;
38 
39 namespace {
40  class MSP430AsmPrinter : public AsmPrinter {
41  public:
42  MSP430AsmPrinter(TargetMachine &TM, MCStreamer &Streamer)
43  : AsmPrinter(TM, Streamer) {}
44 
45  virtual const char *getPassName() const {
46  return "MSP430 Assembly Printer";
47  }
48 
49  void printOperand(const MachineInstr *MI, int OpNum,
50  raw_ostream &O, const char* Modifier = 0);
51  void printSrcMemOperand(const MachineInstr *MI, int OpNum,
52  raw_ostream &O);
53  bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
54  unsigned AsmVariant, const char *ExtraCode,
55  raw_ostream &O);
56  bool PrintAsmMemoryOperand(const MachineInstr *MI,
57  unsigned OpNo, unsigned AsmVariant,
58  const char *ExtraCode, raw_ostream &O);
59  void EmitInstruction(const MachineInstr *MI);
60  };
61 } // end of anonymous namespace
62 
63 
64 void MSP430AsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
65  raw_ostream &O, const char *Modifier) {
66  const MachineOperand &MO = MI->getOperand(OpNum);
67  switch (MO.getType()) {
68  default: llvm_unreachable("Not implemented yet!");
71  return;
73  if (!Modifier || strcmp(Modifier, "nohash"))
74  O << '#';
75  O << MO.getImm();
76  return;
78  O << *MO.getMBB()->getSymbol();
79  return;
81  bool isMemOp = Modifier && !strcmp(Modifier, "mem");
82  uint64_t Offset = MO.getOffset();
83 
84  // If the global address expression is a part of displacement field with a
85  // register base, we should not emit any prefix symbol here, e.g.
86  // mov.w &foo, r1
87  // vs
88  // mov.w glb(r1), r2
89  // Otherwise (!) msp430-as will silently miscompile the output :(
90  if (!Modifier || strcmp(Modifier, "nohash"))
91  O << (isMemOp ? '&' : '#');
92  if (Offset)
93  O << '(' << Offset << '+';
94 
95  O << *getSymbol(MO.getGlobal());
96 
97  if (Offset)
98  O << ')';
99 
100  return;
101  }
103  bool isMemOp = Modifier && !strcmp(Modifier, "mem");
104  O << (isMemOp ? '&' : '#');
105  O << MAI->getGlobalPrefix() << MO.getSymbolName();
106  return;
107  }
108  }
109 }
110 
111 void MSP430AsmPrinter::printSrcMemOperand(const MachineInstr *MI, int OpNum,
112  raw_ostream &O) {
113  const MachineOperand &Base = MI->getOperand(OpNum);
114  const MachineOperand &Disp = MI->getOperand(OpNum+1);
115 
116  // Print displacement first
117 
118  // Imm here is in fact global address - print extra modifier.
119  if (Disp.isImm() && !Base.getReg())
120  O << '&';
121  printOperand(MI, OpNum+1, O, "nohash");
122 
123  // Print register base field
124  if (Base.getReg()) {
125  O << '(';
126  printOperand(MI, OpNum, O);
127  O << ')';
128  }
129 }
130 
131 /// PrintAsmOperand - Print out an operand for an inline asm expression.
132 ///
133 bool MSP430AsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
134  unsigned AsmVariant,
135  const char *ExtraCode, raw_ostream &O) {
136  // Does this asm operand have a single letter operand modifier?
137  if (ExtraCode && ExtraCode[0])
138  return true; // Unknown modifier.
139 
140  printOperand(MI, OpNo, O);
141  return false;
142 }
143 
144 bool MSP430AsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
145  unsigned OpNo, unsigned AsmVariant,
146  const char *ExtraCode,
147  raw_ostream &O) {
148  if (ExtraCode && ExtraCode[0]) {
149  return true; // Unknown modifier.
150  }
151  printSrcMemOperand(MI, OpNo, O);
152  return false;
153 }
154 
155 //===----------------------------------------------------------------------===//
156 void MSP430AsmPrinter::EmitInstruction(const MachineInstr *MI) {
157  MSP430MCInstLower MCInstLowering(OutContext, *this);
158 
159  MCInst TmpInst;
160  MCInstLowering.Lower(MI, TmpInst);
161  OutStreamer.EmitInstruction(TmpInst);
162 }
163 
164 // Force static initialization.
167 }
int strcmp(const char *s1, const char *s2);
const GlobalValue * getGlobal() const
MachineBasicBlock * getMBB() const
static const char * getRegisterName(unsigned RegNo)
const char * getSymbolName() const
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
#define llvm_unreachable(msg)
int64_t getImm() const
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:267
Target TheMSP430Target
int64_t getOffset() const
void LLVMInitializeMSP430AsmPrinter()
MCSymbol * getSymbol() const
MachineOperandType getType() const
unsigned getReg() const
getReg - Returns the register number.
static RegisterPass< NVPTXAllocaHoisting > X("alloca-hoisting","Hoisting alloca instructions in non-entry ""blocks to the entry block")
MachineBasicBlock reference.
Address of a global value.
Name of external global symbol.