LLVM  14.0.0git
ARCInstPrinter.cpp
Go to the documentation of this file.
1 //===- ARCInstPrinter.cpp - ARC MCInst to assembly syntax -------*- C++ -*-===//
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 ARC MCInst to a .s file.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "ARCInstPrinter.h"
14 #include "MCTargetDesc/ARCInfo.h"
15 #include "llvm/ADT/StringExtras.h"
16 #include "llvm/MC/MCExpr.h"
17 #include "llvm/MC/MCInst.h"
18 #include "llvm/MC/MCInstrInfo.h"
19 #include "llvm/MC/MCSymbol.h"
20 #include "llvm/Support/Casting.h"
21 #include "llvm/Support/Debug.h"
23 
24 using namespace llvm;
25 
26 #define DEBUG_TYPE "asm-printer"
27 
28 #include "ARCGenAsmWriter.inc"
29 
30 template <class T>
31 static const char *BadConditionCode(T cc) {
32  LLVM_DEBUG(dbgs() << "Unknown condition code passed: " << cc << "\n");
33  return "{unknown-cc}";
34 }
35 
36 static const char *ARCBRCondCodeToString(ARCCC::BRCondCode BRCC) {
37  switch (BRCC) {
38  case ARCCC::BREQ:
39  return "eq";
40  case ARCCC::BRNE:
41  return "ne";
42  case ARCCC::BRLT:
43  return "lt";
44  case ARCCC::BRGE:
45  return "ge";
46  case ARCCC::BRLO:
47  return "lo";
48  case ARCCC::BRHS:
49  return "hs";
50  }
51  return BadConditionCode(BRCC);
52 }
53 
54 static const char *ARCCondCodeToString(ARCCC::CondCode CC) {
55  switch (CC) {
56  case ARCCC::EQ:
57  return "eq";
58  case ARCCC::NE:
59  return "ne";
60  case ARCCC::P:
61  return "p";
62  case ARCCC::N:
63  return "n";
64  case ARCCC::HS:
65  return "hs";
66  case ARCCC::LO:
67  return "lo";
68  case ARCCC::GT:
69  return "gt";
70  case ARCCC::GE:
71  return "ge";
72  case ARCCC::VS:
73  return "vs";
74  case ARCCC::VC:
75  return "vc";
76  case ARCCC::LT:
77  return "lt";
78  case ARCCC::LE:
79  return "le";
80  case ARCCC::HI:
81  return "hi";
82  case ARCCC::LS:
83  return "ls";
84  case ARCCC::PNZ:
85  return "pnz";
86  case ARCCC::AL:
87  return "al";
88  case ARCCC::NZ:
89  return "nz";
90  case ARCCC::Z:
91  return "z";
92  }
93  return BadConditionCode(CC);
94 }
95 
96 void ARCInstPrinter::printRegName(raw_ostream &OS, unsigned RegNo) const {
97  OS << StringRef(getRegisterName(RegNo)).lower();
98 }
99 
101  StringRef Annot, const MCSubtargetInfo &STI,
102  raw_ostream &O) {
104  printAnnotation(O, Annot);
105 }
106 
107 static void printExpr(const MCExpr *Expr, const MCAsmInfo *MAI,
108  raw_ostream &OS) {
109  int Offset = 0;
110  const MCSymbolRefExpr *SRE;
111 
112  if (const auto *CE = dyn_cast<MCConstantExpr>(Expr)) {
113  OS << "0x";
114  OS.write_hex(CE->getValue());
115  return;
116  }
117 
118  if (const auto *BE = dyn_cast<MCBinaryExpr>(Expr)) {
119  SRE = dyn_cast<MCSymbolRefExpr>(BE->getLHS());
120  const auto *CE = dyn_cast<MCConstantExpr>(BE->getRHS());
121  assert(SRE && CE && "Binary expression must be sym+const.");
122  Offset = CE->getValue();
123  } else {
124  SRE = dyn_cast<MCSymbolRefExpr>(Expr);
125  assert(SRE && "Unexpected MCExpr type.");
126  }
128 
129  // Symbols are prefixed with '@'
130  OS << '@';
131  SRE->getSymbol().print(OS, MAI);
132 
133  if (Offset) {
134  if (Offset > 0)
135  OS << '+';
136  OS << Offset;
137  }
138 }
139 
140 void ARCInstPrinter::printOperand(const MCInst *MI, unsigned OpNum,
141  raw_ostream &O) {
142  const MCOperand &Op = MI->getOperand(OpNum);
143  if (Op.isReg()) {
144  printRegName(O, Op.getReg());
145  return;
146  }
147 
148  if (Op.isImm()) {
149  O << Op.getImm();
150  return;
151  }
152 
153  assert(Op.isExpr() && "unknown operand kind in printOperand");
154  printExpr(Op.getExpr(), &MAI, O);
155 }
156 
157 void ARCInstPrinter::printMemOperandRI(const MCInst *MI, unsigned OpNum,
158  raw_ostream &O) {
159  const MCOperand &base = MI->getOperand(OpNum);
160  const MCOperand &offset = MI->getOperand(OpNum + 1);
161  assert(base.isReg() && "Base should be register.");
162  assert(offset.isImm() && "Offset should be immediate.");
163  printRegName(O, base.getReg());
164  O << "," << offset.getImm();
165 }
166 
167 void ARCInstPrinter::printPredicateOperand(const MCInst *MI, unsigned OpNum,
168  raw_ostream &O) {
169 
170  const MCOperand &Op = MI->getOperand(OpNum);
171  assert(Op.isImm() && "Predicate operand is immediate.");
172  O << ARCCondCodeToString((ARCCC::CondCode)Op.getImm());
173 }
174 
175 void ARCInstPrinter::printBRCCPredicateOperand(const MCInst *MI, unsigned OpNum,
176  raw_ostream &O) {
177  const MCOperand &Op = MI->getOperand(OpNum);
178  assert(Op.isImm() && "Predicate operand is immediate.");
180 }
181 
182 void ARCInstPrinter::printCCOperand(const MCInst *MI, int OpNum,
183  raw_ostream &O) {
184  O << ARCCondCodeToString((ARCCC::CondCode)MI->getOperand(OpNum).getImm());
185 }
186 
187 void ARCInstPrinter::printU6ShiftedBy(unsigned ShiftBy, const MCInst *MI,
188  int OpNum, raw_ostream &O) {
189  const MCOperand &MO = MI->getOperand(OpNum);
190  if (MO.isImm()) {
191  unsigned Value = MO.getImm();
192  unsigned Value2 = Value >> ShiftBy;
193  if (Value2 > 0x3F || (Value2 << ShiftBy != Value)) {
194  errs() << "!!! Instruction has out-of-range U6 immediate operand:\n"
195  << " Opcode is " << MI->getOpcode() << "; operand value is "
196  << Value;
197  if (ShiftBy)
198  errs() << " scaled by " << (1 << ShiftBy) << "\n";
199  assert(false && "instruction has wrong format");
200  }
201  }
202  printOperand(MI, OpNum, O);
203 }
204 
205 void ARCInstPrinter::printU6(const MCInst *MI, int OpNum, raw_ostream &O) {
206  printU6ShiftedBy(0, MI, OpNum, O);
207 }
llvm::MCSymbolRefExpr::getKind
VariantKind getKind() const
Definition: MCExpr.h:400
llvm::ARCInstPrinter::printInstruction
void printInstruction(const MCInst *MI, uint64_t Address, raw_ostream &O)
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:103
llvm
---------------------— PointerInfo ------------------------------------—
Definition: AllocatorList.h:23
llvm::ARCCC::BRLO
@ BRLO
Definition: ARCInfo.h:50
llvm::ARCInstPrinter::getRegisterName
static const char * getRegisterName(unsigned RegNo)
T
llvm::MCAsmInfo
This class is intended to be used as a base class for asm properties and features specific to the tar...
Definition: MCAsmInfo.h:56
cc
src override malloc cc
Definition: CMakeLists.txt:93
llvm::ARCCC::NE
@ NE
Definition: ARCInfo.h:27
llvm::ARCCC::LE
@ LE
Definition: ARCInfo.h:37
llvm::ARCCC::BRHS
@ BRHS
Definition: ARCInfo.h:51
Offset
uint64_t Offset
Definition: ELFObjHandler.cpp:81
llvm::errs
raw_fd_ostream & errs()
This returns a reference to a raw_ostream for standard error.
Definition: raw_ostream.cpp:892
llvm::MCInst
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:184
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:101
ARCBRCondCodeToString
static const char * ARCBRCondCodeToString(ARCCC::BRCondCode BRCC)
Definition: ARCInstPrinter.cpp:36
llvm::ARCCC::LS
@ LS
Definition: ARCInfo.h:39
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
llvm::ARCCC::GT
@ GT
Definition: ARCInfo.h:34
ARCInstPrinter.h
MCInstrInfo.h
llvm::MCOperand::getImm
int64_t getImm() const
Definition: MCInst.h:80
MCSymbol.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::MCSymbolRefExpr::getSymbol
const MCSymbol & getSymbol() const
Definition: MCExpr.h:398
llvm::ARCCC::N
@ N
Definition: ARCInfo.h:29
ARCInfo.h
llvm::MCSymbol::print
void print(raw_ostream &OS, const MCAsmInfo *MAI) const
print - Print the value to the stream OS.
Definition: MCSymbol.cpp:59
llvm::MCInstPrinter::printAnnotation
void printAnnotation(raw_ostream &OS, StringRef Annot)
Utility function for printing annotations.
Definition: MCInstPrinter.cpp:49
llvm::ARCCC::VC
@ VC
Definition: ARCInfo.h:33
llvm::RISCVFenceField::O
@ O
Definition: RISCVBaseInfo.h:197
llvm::ARCCC::EQ
@ EQ
Definition: ARCInfo.h:26
llvm::MCOperand::isImm
bool isImm() const
Definition: MCInst.h:62
uint64_t
llvm::ARCInstPrinter::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: ARCInstPrinter.cpp:100
llvm::ARCCC::LO
@ LO
Definition: ARCInfo.h:30
llvm::ARCCC::BRCondCode
BRCondCode
Definition: ARCInfo.h:45
llvm::ARCCC::CondCode
CondCode
Definition: ARCInfo.h:24
StringExtras.h
printExpr
static void printExpr(const MCExpr *Expr, const MCAsmInfo *MAI, raw_ostream &OS)
Definition: ARCInstPrinter.cpp:107
llvm::StringRef::lower
LLVM_NODISCARD std::string lower() const
Definition: StringRef.cpp:105
llvm::HighlightColor::Address
@ Address
llvm::ARCInstPrinter::printRegName
void printRegName(raw_ostream &OS, unsigned RegNo) const override
Print the assembler register name.
Definition: ARCInstPrinter.cpp:96
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::ARCCC::GE
@ GE
Definition: ARCInfo.h:35
llvm::ARCInstPrinter::printU6
void printU6(const MCInst *MI, int OpNum, raw_ostream &O)
Definition: ARCInstPrinter.cpp:205
base
therefore end up llgh r3 lr r0 br r14 but truncating the load would lh r3 br r14 Functions ret i64 and ought to be implemented ngr r0 br r14 but two address optimizations reverse the order of the AND and ngr r2 lgr r0 br r14 CodeGen SystemZ and ll has several examples of this Out of range displacements are usually handled by loading the full address into a register In many cases it would be better to create an anchor point instead E g i64 base
Definition: README.txt:125
llvm::MCSymbolRefExpr
Represent a reference to a symbol from inside an expression.
Definition: MCExpr.h:192
llvm::ARCCC::BRLT
@ BRLT
Definition: ARCInfo.h:48
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
llvm::ARCCC::P
@ P
Definition: ARCInfo.h:28
llvm::ARCCC::BRGE
@ BRGE
Definition: ARCInfo.h:49
llvm::AMDGPU::SendMsg::Op
Op
Definition: SIDefines.h:321
ARCCondCodeToString
static const char * ARCCondCodeToString(ARCCC::CondCode CC)
Definition: ARCInstPrinter.cpp:54
Casting.h
llvm::TargetStackID::Value
Value
Definition: TargetFrameLowering.h:27
llvm::ARCCC::Z
@ Z
Definition: ARCInfo.h:41
llvm::ARCCC::AL
@ AL
Definition: ARCInfo.h:25
BadConditionCode
static const char * BadConditionCode(T cc)
Definition: ARCInstPrinter.cpp:31
llvm::MCInstPrinter::MAI
const MCAsmInfo & MAI
Definition: MCInstPrinter.h:49
llvm::ARCInstPrinter::printCCOperand
void printCCOperand(const MCInst *MI, int OpNum, raw_ostream &O)
Definition: ARCInstPrinter.cpp:182
llvm::ARCCC::HI
@ HI
Definition: ARCInfo.h:38
llvm::ARCCC::PNZ
@ PNZ
Definition: ARCInfo.h:40
llvm::ARCCC::VS
@ VS
Definition: ARCInfo.h:32
llvm::MCOperand
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:36
llvm::ARCCC::NZ
@ NZ
Definition: ARCInfo.h:42
llvm::MCSymbolRefExpr::VK_None
@ VK_None
Definition: MCExpr.h:195
llvm::ARCCC::LT
@ LT
Definition: ARCInfo.h:36
raw_ostream.h
llvm::ARCCC::BRNE
@ BRNE
Definition: ARCInfo.h:47
MCExpr.h
llvm::MCSubtargetInfo
Generic base class for all target subtargets.
Definition: MCSubtargetInfo.h:75
llvm::Value
LLVM Value Representation.
Definition: Value.h:75
llvm::MCExpr
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:35
Debug.h
llvm::ARCCC::HS
@ HS
Definition: ARCInfo.h:31
llvm::ARCCC::BREQ
@ BREQ
Definition: ARCInfo.h:46
llvm::raw_ostream::write_hex
raw_ostream & write_hex(unsigned long long N)
Output N in hexadecimal, without any prefix or padding.
Definition: raw_ostream.cpp:140