LLVM  8.0.1
AVRInstPrinter.cpp
Go to the documentation of this file.
1 //===-- AVRInstPrinter.cpp - Convert AVR MCInst to assembly syntax --------===//
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 class prints an AVR MCInst to a .s file.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "AVRInstPrinter.h"
15 
17 
18 #include "llvm/MC/MCExpr.h"
19 #include "llvm/MC/MCInst.h"
20 #include "llvm/MC/MCInstrDesc.h"
21 #include "llvm/MC/MCInstrInfo.h"
22 #include "llvm/MC/MCRegisterInfo.h"
25 
26 #include <cstring>
27 
28 #define DEBUG_TYPE "asm-printer"
29 
30 namespace llvm {
31 
32 // Include the auto-generated portion of the assembly writer.
33 #define PRINT_ALIAS_INSTR
34 #include "AVRGenAsmWriter.inc"
35 
37  StringRef Annot, const MCSubtargetInfo &STI) {
38  unsigned Opcode = MI->getOpcode();
39 
40  // First handle load and store instructions with postinc or predec
41  // of the form "ld reg, X+".
42  // TODO: We should be able to rewrite this using TableGen data.
43  switch (Opcode) {
44  case AVR::LDRdPtr:
45  case AVR::LDRdPtrPi:
46  case AVR::LDRdPtrPd:
47  O << "\tld\t";
48  printOperand(MI, 0, O);
49  O << ", ";
50 
51  if (Opcode == AVR::LDRdPtrPd)
52  O << '-';
53 
54  printOperand(MI, 1, O);
55 
56  if (Opcode == AVR::LDRdPtrPi)
57  O << '+';
58  break;
59  case AVR::STPtrRr:
60  O << "\tst\t";
61  printOperand(MI, 0, O);
62  O << ", ";
63  printOperand(MI, 1, O);
64  break;
65  case AVR::STPtrPiRr:
66  case AVR::STPtrPdRr:
67  O << "\tst\t";
68 
69  if (Opcode == AVR::STPtrPdRr)
70  O << '-';
71 
72  printOperand(MI, 1, O);
73 
74  if (Opcode == AVR::STPtrPiRr)
75  O << '+';
76 
77  O << ", ";
78  printOperand(MI, 2, O);
79  break;
80  default:
81  if (!printAliasInstr(MI, O))
82  printInstruction(MI, O);
83 
84  printAnnotation(O, Annot);
85  break;
86  }
87 }
88 
89 const char *AVRInstPrinter::getPrettyRegisterName(unsigned RegNum,
90  MCRegisterInfo const &MRI) {
91  // GCC prints register pairs by just printing the lower register
92  // If the register contains a subregister, print it instead
93  if (MRI.getNumSubRegIndices() > 0) {
94  unsigned RegLoNum = MRI.getSubReg(RegNum, AVR::sub_lo);
95  RegNum = (RegLoNum != AVR::NoRegister) ? RegLoNum : RegNum;
96  }
97 
98  return getRegisterName(RegNum);
99 }
100 
101 void AVRInstPrinter::printOperand(const MCInst *MI, unsigned OpNo,
102  raw_ostream &O) {
103  const MCOperand &Op = MI->getOperand(OpNo);
104  const MCOperandInfo &MOI = this->MII.get(MI->getOpcode()).OpInfo[OpNo];
105 
106  if (Op.isReg()) {
107  bool isPtrReg = (MOI.RegClass == AVR::PTRREGSRegClassID) ||
108  (MOI.RegClass == AVR::PTRDISPREGSRegClassID) ||
109  (MOI.RegClass == AVR::ZREGRegClassID);
110 
111  if (isPtrReg) {
112  O << getRegisterName(Op.getReg(), AVR::ptr);
113  } else {
114  O << getPrettyRegisterName(Op.getReg(), MRI);
115  }
116  } else if (Op.isImm()) {
117  O << Op.getImm();
118  } else {
119  assert(Op.isExpr() && "Unknown operand kind in printOperand");
120  O << *Op.getExpr();
121  }
122 }
123 
124 /// This is used to print an immediate value that ends up
125 /// being encoded as a pc-relative value.
126 void AVRInstPrinter::printPCRelImm(const MCInst *MI, unsigned OpNo,
127  raw_ostream &O) {
128  const MCOperand &Op = MI->getOperand(OpNo);
129 
130  if (Op.isImm()) {
131  int64_t Imm = Op.getImm();
132  O << '.';
133 
134  // Print a position sign if needed.
135  // Negative values have their sign printed automatically.
136  if (Imm >= 0)
137  O << '+';
138 
139  O << Imm;
140  } else {
141  assert(Op.isExpr() && "Unknown pcrel immediate operand");
142  O << *Op.getExpr();
143  }
144 }
145 
146 void AVRInstPrinter::printMemri(const MCInst *MI, unsigned OpNo,
147  raw_ostream &O) {
148  assert(MI->getOperand(OpNo).isReg() && "Expected a register for the first operand");
149 
150  const MCOperand &OffsetOp = MI->getOperand(OpNo + 1);
151 
152  // Print the register.
153  printOperand(MI, OpNo, O);
154 
155  // Print the {+,-}offset.
156  if (OffsetOp.isImm()) {
157  int64_t Offset = OffsetOp.getImm();
158 
159  if (Offset >= 0)
160  O << '+';
161 
162  O << Offset;
163  } else if (OffsetOp.isExpr()) {
164  O << *OffsetOp.getExpr();
165  } else {
166  llvm_unreachable("unknown type for offset");
167  }
168 }
169 
170 } // end of namespace llvm
171 
bool isImm() const
Definition: MCInst.h:59
This class represents lattice values for constants.
Definition: AllocatorList.h:24
bool isReg() const
Definition: MCInst.h:58
unsigned getReg() const
Returns the register number.
Definition: MCInst.h:65
const MCExpr * getExpr() const
Definition: MCInst.h:96
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:161
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
int64_t getImm() const
Definition: MCInst.h:76
unsigned getSubReg(unsigned Reg, unsigned Idx) const
Returns the physical register number of sub-register "Index" for physical register RegNo...
bool isExpr() const
Definition: MCInst.h:61
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
const MCOperand & getOperand(unsigned i) const
Definition: MCInst.h:182
void printInst(const MCInst *MI, raw_ostream &O, StringRef Annot, const MCSubtargetInfo &STI) override
Print the specified MCInst to the specified raw_ostream.
int16_t RegClass
This specifies the register class enumeration of the operand if the operand is a register.
Definition: MCInstrDesc.h:73
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode...
Definition: MCInstrInfo.h:45
Generic base class for all target subtargets.
const MCInstrInfo & MII
Definition: MCInstPrinter.h:47
unsigned getNumSubRegIndices() const
Return the number of sub-register indices understood by the target.
static const char * getPrettyRegisterName(unsigned RegNo, MCRegisterInfo const &MRI)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
void printAnnotation(raw_ostream &OS, StringRef Annot)
Utility function for printing annotations.
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:46
IRTranslator LLVM IR MI
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
This holds information about one operand of a machine instruction, indicating the register class for ...
Definition: MCInstrDesc.h:67
unsigned getOpcode() const
Definition: MCInst.h:174
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:35
const MCRegisterInfo & MRI
Definition: MCInstPrinter.h:48