LLVM  14.0.0git
AVRInstPrinter.cpp
Go to the documentation of this file.
1 //===-- AVRInstPrinter.cpp - Convert AVR MCInst to assembly syntax --------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This class prints an AVR MCInst to a .s file.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "AVRInstPrinter.h"
14 
16 
17 #include "llvm/MC/MCExpr.h"
18 #include "llvm/MC/MCInst.h"
19 #include "llvm/MC/MCInstrDesc.h"
20 #include "llvm/MC/MCInstrInfo.h"
21 #include "llvm/MC/MCRegisterInfo.h"
24 
25 #include <cstring>
26 
27 #define DEBUG_TYPE "asm-printer"
28 
29 namespace llvm {
30 
31 // Include the auto-generated portion of the assembly writer.
32 #define PRINT_ALIAS_INSTR
33 #include "AVRGenAsmWriter.inc"
34 
36  StringRef Annot, const MCSubtargetInfo &STI,
37  raw_ostream &O) {
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, Address, O))
82  printInstruction(MI, Address, 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 MCOperandInfo &MOI = this->MII.get(MI->getOpcode()).OpInfo[OpNo];
104  if (MOI.RegClass == AVR::ZREGRegClassID) {
105  // Special case for the Z register, which sometimes doesn't have an operand
106  // in the MCInst.
107  O << "Z";
108  return;
109  }
110 
111  if (OpNo >= MI->size()) {
112  // Not all operands are correctly disassembled at the moment. This means
113  // that some machine instructions won't have all the necessary operands
114  // set.
115  // To avoid asserting, print <unknown> instead until the necessary support
116  // has been implemented.
117  O << "<unknown>";
118  return;
119  }
120 
121  const MCOperand &Op = MI->getOperand(OpNo);
122 
123  if (Op.isReg()) {
124  bool isPtrReg = (MOI.RegClass == AVR::PTRREGSRegClassID) ||
125  (MOI.RegClass == AVR::PTRDISPREGSRegClassID) ||
126  (MOI.RegClass == AVR::ZREGRegClassID);
127 
128  if (isPtrReg) {
129  O << getRegisterName(Op.getReg(), AVR::ptr);
130  } else {
131  O << getPrettyRegisterName(Op.getReg(), MRI);
132  }
133  } else if (Op.isImm()) {
134  O << formatImm(Op.getImm());
135  } else {
136  assert(Op.isExpr() && "Unknown operand kind in printOperand");
137  O << *Op.getExpr();
138  }
139 }
140 
141 /// This is used to print an immediate value that ends up
142 /// being encoded as a pc-relative value.
143 void AVRInstPrinter::printPCRelImm(const MCInst *MI, unsigned OpNo,
144  raw_ostream &O) {
145  if (OpNo >= MI->size()) {
146  // Not all operands are correctly disassembled at the moment. This means
147  // that some machine instructions won't have all the necessary operands
148  // set.
149  // To avoid asserting, print <unknown> instead until the necessary support
150  // has been implemented.
151  O << "<unknown>";
152  return;
153  }
154 
155  const MCOperand &Op = MI->getOperand(OpNo);
156 
157  if (Op.isImm()) {
158  int64_t Imm = Op.getImm();
159  O << '.';
160 
161  // Print a position sign if needed.
162  // Negative values have their sign printed automatically.
163  if (Imm >= 0)
164  O << '+';
165 
166  O << Imm;
167  } else {
168  assert(Op.isExpr() && "Unknown pcrel immediate operand");
169  O << *Op.getExpr();
170  }
171 }
172 
173 void AVRInstPrinter::printMemri(const MCInst *MI, unsigned OpNo,
174  raw_ostream &O) {
175  assert(MI->getOperand(OpNo).isReg() &&
176  "Expected a register for the first operand");
177 
178  const MCOperand &OffsetOp = MI->getOperand(OpNo + 1);
179 
180  // Print the register.
181  printOperand(MI, OpNo, O);
182 
183  // Print the {+,-}offset.
184  if (OffsetOp.isImm()) {
185  int64_t Offset = OffsetOp.getImm();
186 
187  if (Offset >= 0)
188  O << '+';
189 
190  O << Offset;
191  } else if (OffsetOp.isExpr()) {
192  O << *OffsetOp.getExpr();
193  } else {
194  llvm_unreachable("unknown type for offset");
195  }
196 }
197 
198 } // end of namespace llvm
llvm::MCInstPrinter::MII
const MCInstrInfo & MII
Definition: MCInstPrinter.h:50
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:103
llvm
---------------------— PointerInfo ------------------------------------—
Definition: AllocatorList.h:23
AVRInstPrinter.h
MCInstrDesc.h
ErrorHandling.h
Offset
uint64_t Offset
Definition: ELFObjHandler.cpp:81
llvm::MCInst
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:184
llvm::MCRegisterInfo::getSubReg
MCRegister getSubReg(MCRegister Reg, unsigned Idx) const
Returns the physical register number of sub-register "Index" for physical register RegNo.
Definition: MCRegisterInfo.cpp:32
llvm::MCRegisterInfo::getNumSubRegIndices
unsigned getNumSubRegIndices() const
Return the number of sub-register indices understood by the target.
Definition: MCRegisterInfo.h:498
llvm::MCOperandInfo
This holds information about one operand of a machine instruction, indicating the register class for ...
Definition: MCInstrDesc.h:83
llvm::MCInstPrinter::MRI
const MCRegisterInfo & MRI
Definition: MCInstPrinter.h:51
FormattedStream.h
MCInstrInfo.h
MCInst.h
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:53
llvm::MCOperandInfo::RegClass
int16_t RegClass
This specifies the register class enumeration of the operand if the operand is a register.
Definition: MCInstrDesc.h:89
llvm::MCInstPrinter::printAnnotation
void printAnnotation(raw_ostream &OS, StringRef Annot)
Utility function for printing annotations.
Definition: MCInstPrinter.cpp:49
llvm::RISCVFenceField::O
@ O
Definition: RISCVBaseInfo.h:192
uint64_t
llvm::AVRInstPrinter::getPrettyRegisterName
static const char * getPrettyRegisterName(unsigned RegNo, MCRegisterInfo const &MRI)
Definition: AVRInstPrinter.cpp:89
MCRegisterInfo.h
llvm::HighlightColor::Address
@ Address
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::MCInstrDesc::OpInfo
const MCOperandInfo * OpInfo
Definition: MCInstrDesc.h:206
AVRMCTargetDesc.h
llvm::MCInstPrinter::formatImm
format_object< int64_t > formatImm(int64_t Value) const
Utility function to print immediates in decimal or hex.
Definition: MCInstPrinter.h:134
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:136
llvm::MCRegisterInfo
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
Definition: MCRegisterInfo.h:135
MRI
unsigned const MachineRegisterInfo * MRI
Definition: AArch64AdvSIMDScalarPass.cpp:105
llvm::AMDGPU::SendMsg::Op
Op
Definition: SIDefines.h:321
llvm::MCInst::getOpcode
unsigned getOpcode() const
Definition: MCInst.h:198
llvm::MCInstrInfo::get
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
Definition: MCInstrInfo.h:62
MCExpr.h
llvm::MCSubtargetInfo
Generic base class for all target subtargets.
Definition: MCSubtargetInfo.h:75
llvm::AVRInstPrinter::printInst
void printInst(const MCInst *MI, uint64_t Address, StringRef Annot, const MCSubtargetInfo &STI, raw_ostream &O) override
Print the specified MCInst to the specified raw_ostream.
Definition: AVRInstPrinter.cpp:35