LLVM  4.0.0
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 #include "MSP430.h"
17 #include "MSP430InstrInfo.h"
18 #include "MSP430MCInstLower.h"
19 #include "MSP430TargetMachine.h"
25 #include "llvm/IR/Constants.h"
26 #include "llvm/IR/DerivedTypes.h"
27 #include "llvm/IR/Mangler.h"
28 #include "llvm/IR/Module.h"
29 #include "llvm/MC/MCAsmInfo.h"
30 #include "llvm/MC/MCInst.h"
31 #include "llvm/MC/MCStreamer.h"
32 #include "llvm/MC/MCSymbol.h"
35 using namespace llvm;
36 
37 #define DEBUG_TYPE "asm-printer"
38 
39 namespace {
40  class MSP430AsmPrinter : public AsmPrinter {
41  public:
42  MSP430AsmPrinter(TargetMachine &TM, std::unique_ptr<MCStreamer> Streamer)
43  : AsmPrinter(TM, std::move(Streamer)) {}
44 
45  StringRef getPassName() const override { return "MSP430 Assembly Printer"; }
46 
47  void printOperand(const MachineInstr *MI, int OpNum,
48  raw_ostream &O, const char* Modifier = nullptr);
49  void printSrcMemOperand(const MachineInstr *MI, int OpNum,
50  raw_ostream &O);
51  bool PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
52  unsigned AsmVariant, const char *ExtraCode,
53  raw_ostream &O) override;
54  bool PrintAsmMemoryOperand(const MachineInstr *MI,
55  unsigned OpNo, unsigned AsmVariant,
56  const char *ExtraCode, raw_ostream &O) override;
57  void EmitInstruction(const MachineInstr *MI) override;
58  };
59 } // end of anonymous namespace
60 
61 
62 void MSP430AsmPrinter::printOperand(const MachineInstr *MI, int OpNum,
63  raw_ostream &O, const char *Modifier) {
64  const MachineOperand &MO = MI->getOperand(OpNum);
65  switch (MO.getType()) {
66  default: llvm_unreachable("Not implemented yet!");
69  return;
71  if (!Modifier || strcmp(Modifier, "nohash"))
72  O << '#';
73  O << MO.getImm();
74  return;
76  MO.getMBB()->getSymbol()->print(O, MAI);
77  return;
79  bool isMemOp = Modifier && !strcmp(Modifier, "mem");
80  uint64_t Offset = MO.getOffset();
81 
82  // If the global address expression is a part of displacement field with a
83  // register base, we should not emit any prefix symbol here, e.g.
84  // mov.w &foo, r1
85  // vs
86  // mov.w glb(r1), r2
87  // Otherwise (!) msp430-as will silently miscompile the output :(
88  if (!Modifier || strcmp(Modifier, "nohash"))
89  O << (isMemOp ? '&' : '#');
90  if (Offset)
91  O << '(' << Offset << '+';
92 
93  getSymbol(MO.getGlobal())->print(O, MAI);
94 
95  if (Offset)
96  O << ')';
97 
98  return;
99  }
100  }
101 }
102 
103 void MSP430AsmPrinter::printSrcMemOperand(const MachineInstr *MI, int OpNum,
104  raw_ostream &O) {
105  const MachineOperand &Base = MI->getOperand(OpNum);
106  const MachineOperand &Disp = MI->getOperand(OpNum+1);
107 
108  // Print displacement first
109 
110  // Imm here is in fact global address - print extra modifier.
111  if (Disp.isImm() && !Base.getReg())
112  O << '&';
113  printOperand(MI, OpNum+1, O, "nohash");
114 
115  // Print register base field
116  if (Base.getReg()) {
117  O << '(';
118  printOperand(MI, OpNum, O);
119  O << ')';
120  }
121 }
122 
123 /// PrintAsmOperand - Print out an operand for an inline asm expression.
124 ///
125 bool MSP430AsmPrinter::PrintAsmOperand(const MachineInstr *MI, unsigned OpNo,
126  unsigned AsmVariant,
127  const char *ExtraCode, raw_ostream &O) {
128  // Does this asm operand have a single letter operand modifier?
129  if (ExtraCode && ExtraCode[0])
130  return true; // Unknown modifier.
131 
132  printOperand(MI, OpNo, O);
133  return false;
134 }
135 
136 bool MSP430AsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI,
137  unsigned OpNo, unsigned AsmVariant,
138  const char *ExtraCode,
139  raw_ostream &O) {
140  if (ExtraCode && ExtraCode[0]) {
141  return true; // Unknown modifier.
142  }
143  printSrcMemOperand(MI, OpNo, O);
144  return false;
145 }
146 
147 //===----------------------------------------------------------------------===//
148 void MSP430AsmPrinter::EmitInstruction(const MachineInstr *MI) {
149  MSP430MCInstLower MCInstLowering(OutContext, *this);
150 
151  MCInst TmpInst;
152  MCInstLowering.Lower(MI, TmpInst);
153  EmitToStreamer(*OutStreamer, TmpInst);
154 }
155 
156 // Force static initialization.
159 }
Target & getTheMSP430Target()
const GlobalValue * getGlobal() const
void print(raw_ostream &OS, const MCAsmInfo *MAI) const
print - Print the value to the stream OS.
Definition: MCSymbol.cpp:53
MachineBasicBlock * getMBB() const
static const char * getRegisterName(unsigned RegNo)
MachineBasicBlock reference.
Maximum length of the test input libFuzzer tries to guess a good value based on the corpus and reports it always prefer smaller inputs during the corpus shuffle When libFuzzer itself reports a bug this exit code will be used If indicates the maximal total time in seconds to run the fuzzer minimizes the provided crash input Use with strcmp
This file declares the MachineConstantPool class which is an abstract constant pool to keep track of ...
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
MSP430MCInstLower - This class is used to lower an MachineInstr into an MCInst.
int64_t getImm() const
Expected< const typename ELFT::Sym * > getSymbol(typename ELFT::SymRange Symbols, uint32_t Index)
Definition: Object/ELF.h:236
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:150
Address of a global value.
This file contains the declarations for the subclasses of Constant, which represent the different fla...
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:279
This class is intended to be used as a driving class for all asm writers.
Definition: AsmPrinter.h:67
uint32_t Offset
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang","erlang-compatible garbage collector")
int64_t getOffset() const
Return the offset from the symbol in this operand.
void LLVMInitializeMSP430AsmPrinter()
MCSymbol * getSymbol() const
Return the MCSymbol for this basic block.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
MachineOperand class - Representation of each machine instruction operand.
Module.h This file contains the declarations for the Module class.
Representation of each machine instruction.
Definition: MachineInstr.h:52
MachineOperandType getType() const
getType - Returns the MachineOperandType for this operand.
static bool printOperand(raw_ostream &OS, const SelectionDAG *G, const SDValue Value)
unsigned getReg() const
getReg - Returns the register number.
RegisterAsmPrinter - Helper template for registering a target specific assembly printer, for use in the target machine initialization function.
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:44
Primary interface to the complete machine description for the target machine.
IRTranslator LLVM IR MI
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:47