LLVM  15.0.0git
CSKYMCCodeEmitter.cpp
Go to the documentation of this file.
1 //===-- CSKYMCCodeEmitter.cpp - CSKY Code Emitter interface ---------------===//
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 file implements the CSKYMCCodeEmitter class.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "CSKYMCCodeEmitter.h"
14 #include "CSKYMCExpr.h"
16 #include "llvm/ADT/Statistic.h"
17 #include "llvm/MC/MCInstBuilder.h"
18 #include "llvm/MC/MCInstrInfo.h"
19 #include "llvm/MC/MCRegisterInfo.h"
21 #include "llvm/Support/Casting.h"
23 
24 using namespace llvm;
25 
26 #define DEBUG_TYPE "csky-mccode-emitter"
27 
28 STATISTIC(MCNumEmitted, "Number of MC instructions emitted");
29 
30 unsigned CSKYMCCodeEmitter::getOImmOpValue(const MCInst &MI, unsigned Idx,
32  const MCSubtargetInfo &STI) const {
33  const MCOperand &MO = MI.getOperand(Idx);
34  assert(MO.isImm() && "Unexpected MO type.");
35  return MO.getImm() - 1;
36 }
37 
38 unsigned
41  const MCSubtargetInfo &STI) const {
42  const MCOperand &MO = MI.getOperand(Idx);
43  assert(MO.isImm() && "Unexpected MO type.");
44 
45  auto V = (MO.getImm() <= 3) ? 4 : MO.getImm();
46  return V - 1;
47 }
48 
49 unsigned
52  const MCSubtargetInfo &STI) const {
53  const MCOperand &MSB = MI.getOperand(Idx);
54  const MCOperand &LSB = MI.getOperand(Idx + 1);
55  assert(MSB.isImm() && LSB.isImm() && "Unexpected MO type.");
56 
57  return MSB.getImm() - LSB.getImm();
58 }
59 
60 static void writeData(uint32_t Bin, unsigned Size, raw_ostream &OS) {
61  uint16_t LO16 = static_cast<uint16_t>(Bin);
62  uint16_t HI16 = static_cast<uint16_t>(Bin >> 16);
63 
64  if (Size == 4)
65  support::endian::write<uint16_t>(OS, HI16, support::little);
66 
67  support::endian::write<uint16_t>(OS, LO16, support::little);
68 }
69 
72  const MCSubtargetInfo &STI) const {
73 
74  MCInst TmpInst;
75 
76  uint32_t Binary;
77 
78  TmpInst =
79  MCInstBuilder(MI.getOpcode() == CSKY::JBT_E ? CSKY::BF16 : CSKY::BT16)
80  .addOperand(MI.getOperand(0))
81  .addImm(6);
82  Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
83  writeData(Binary, 2, OS);
84 
85  if (!STI.getFeatureBits()[CSKY::Has2E3])
86  TmpInst = MCInstBuilder(CSKY::BR32)
87  .addOperand(MI.getOperand(1))
88  .addOperand(MI.getOperand(2));
89  else
90  TmpInst = MCInstBuilder(CSKY::JMPI32).addOperand(MI.getOperand(2));
91  Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
92  Fixups[Fixups.size() - 1].setOffset(2);
93  writeData(Binary, 4, OS);
94 }
95 
98  const MCSubtargetInfo &STI) const {
99 
100  MCInst TmpInst;
101  uint32_t Binary;
102  unsigned Size = MI.getOpcode() == CSKY::NEG32 ? 4 : 2;
103 
104  TmpInst = MCInstBuilder(Size == 4 ? CSKY::NOT32 : CSKY::NOT16)
105  .addOperand(MI.getOperand(0))
106  .addOperand(MI.getOperand(1));
107  Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
108  writeData(Binary, Size, OS);
109 
110  TmpInst = MCInstBuilder(Size == 4 ? CSKY::ADDI32 : CSKY::ADDI16)
111  .addOperand(MI.getOperand(0))
112  .addOperand(MI.getOperand(0))
113  .addImm(1);
114  Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
115  writeData(Binary, Size, OS);
116 }
117 
120  const MCSubtargetInfo &STI) const {
121 
122  MCInst TmpInst;
123  uint32_t Binary;
124  unsigned Size = MI.getOpcode() == CSKY::RSUBI32 ? 4 : 2;
125 
126  TmpInst = MCInstBuilder(Size == 4 ? CSKY::NOT32 : CSKY::NOT16)
127  .addOperand(MI.getOperand(0))
128  .addOperand(MI.getOperand(1));
129  Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
130  writeData(Binary, Size, OS);
131 
132  TmpInst = MCInstBuilder(Size == 4 ? CSKY::ADDI32 : CSKY::ADDI16)
133  .addOperand(MI.getOperand(0))
134  .addOperand(MI.getOperand(0))
135  .addImm(MI.getOperand(2).getImm() + 1);
136  Binary = getBinaryCodeForInstr(TmpInst, Fixups, STI);
137  writeData(Binary, Size, OS);
138 }
139 
142  const MCSubtargetInfo &STI) const {
143  const MCInstrDesc &Desc = MII.get(MI.getOpcode());
144  unsigned Size = Desc.getSize();
145 
146  MCInst TmpInst;
147 
148  switch (MI.getOpcode()) {
149  default:
150  TmpInst = MI;
151  break;
152  case CSKY::JBT_E:
153  case CSKY::JBF_E:
154  expandJBTF(MI, OS, Fixups, STI);
155  MCNumEmitted += 2;
156  return;
157  case CSKY::NEG32:
158  case CSKY::NEG16:
159  expandNEG(MI, OS, Fixups, STI);
160  MCNumEmitted += 2;
161  return;
162  case CSKY::RSUBI32:
163  case CSKY::RSUBI16:
164  expandRSUBI(MI, OS, Fixups, STI);
165  MCNumEmitted += 2;
166  return;
167  case CSKY::JBSR32:
168  TmpInst = MCInstBuilder(CSKY::BSR32).addOperand(MI.getOperand(0));
169  break;
170  case CSKY::JBR16:
171  TmpInst = MCInstBuilder(CSKY::BR16).addOperand(MI.getOperand(0));
172  break;
173  case CSKY::JBR32:
174  TmpInst = MCInstBuilder(CSKY::BR32).addOperand(MI.getOperand(0));
175  break;
176  case CSKY::JBT16:
177  TmpInst = MCInstBuilder(CSKY::BT16)
178  .addOperand(MI.getOperand(0))
179  .addOperand(MI.getOperand(1));
180  break;
181  case CSKY::JBT32:
182  TmpInst = MCInstBuilder(CSKY::BT32)
183  .addOperand(MI.getOperand(0))
184  .addOperand(MI.getOperand(1));
185  break;
186  case CSKY::JBF16:
187  TmpInst = MCInstBuilder(CSKY::BF16)
188  .addOperand(MI.getOperand(0))
189  .addOperand(MI.getOperand(1));
190  break;
191  case CSKY::JBF32:
192  TmpInst = MCInstBuilder(CSKY::BF32)
193  .addOperand(MI.getOperand(0))
194  .addOperand(MI.getOperand(1));
195  break;
196  case CSKY::LRW32_Gen:
197  TmpInst = MCInstBuilder(CSKY::LRW32)
198  .addOperand(MI.getOperand(0))
199  .addOperand(MI.getOperand(2));
200  break;
201  case CSKY::LRW16_Gen:
202  TmpInst = MCInstBuilder(CSKY::LRW16)
203  .addOperand(MI.getOperand(0))
204  .addOperand(MI.getOperand(2));
205  break;
206  case CSKY::CMPLEI32:
207  TmpInst = MCInstBuilder(CSKY::CMPLTI32)
208  .addOperand(MI.getOperand(0))
209  .addOperand(MI.getOperand(1))
210  .addImm(MI.getOperand(2).getImm() + 1);
211  break;
212  case CSKY::CMPLEI16:
213  TmpInst = MCInstBuilder(CSKY::CMPLTI16)
214  .addOperand(MI.getOperand(0))
215  .addOperand(MI.getOperand(1))
216  .addImm(MI.getOperand(2).getImm() + 1);
217  break;
218  case CSKY::ROTRI32:
219  TmpInst = MCInstBuilder(CSKY::ROTLI32)
220  .addOperand(MI.getOperand(0))
221  .addOperand(MI.getOperand(1))
222  .addImm(32 - MI.getOperand(2).getImm());
223  break;
224  case CSKY::BGENI:
225  auto V = 1 << MI.getOperand(1).getImm();
226  TmpInst =
227  MCInstBuilder(CSKY::MOVI32).addOperand(MI.getOperand(0)).addImm(V);
228  break;
229  }
230 
231  ++MCNumEmitted;
232 
233  uint32_t Bin = getBinaryCodeForInstr(TmpInst, Fixups, STI);
234 
235  uint16_t LO16 = static_cast<uint16_t>(Bin);
236  uint16_t HI16 = static_cast<uint16_t>(Bin >> 16);
237 
238  if (Size == 4)
239  support::endian::write<uint16_t>(OS, HI16, support::little);
240 
241  support::endian::write<uint16_t>(OS, LO16, support::little);
242 }
243 
244 unsigned
247  const MCSubtargetInfo &STI) const {
248  if (MO.isReg())
249  return Ctx.getRegisterInfo()->getEncodingValue(MO.getReg());
250 
251  if (MO.isImm())
252  return static_cast<unsigned>(MO.getImm());
253 
254  llvm_unreachable("Unhandled expression!");
255  return 0;
256 }
257 
258 unsigned
261  const MCSubtargetInfo &STI) const {
262  assert(MI.getOperand(Idx).isReg() && "Unexpected MO type.");
263  assert(MI.getOperand(Idx + 1).isImm() && "Unexpected MO type.");
264 
265  unsigned Ry = MI.getOperand(Idx).getReg();
266  unsigned Rz = MI.getOperand(Idx + 1).getImm();
267 
268  unsigned Imm = Ctx.getRegisterInfo()->getEncodingValue(Rz) -
270 
271  return ((Ctx.getRegisterInfo()->getEncodingValue(Ry) << 5) | Imm);
272 }
273 
274 unsigned
277  const MCSubtargetInfo &STI) const {
278  unsigned Reg1 =
279  Ctx.getRegisterInfo()->getEncodingValue(MI.getOperand(Op).getReg());
280  unsigned Reg2 =
281  Ctx.getRegisterInfo()->getEncodingValue(MI.getOperand(Op + 1).getReg());
282 
283  unsigned Binary = ((Reg1 & 0x1f) << 5) | (Reg2 - Reg1);
284 
285  return Binary;
286 }
287 
288 unsigned CSKYMCCodeEmitter::getImmJMPIX(const MCInst &MI, unsigned Idx,
290  const MCSubtargetInfo &STI) const {
291  if (MI.getOperand(Idx).getImm() == 16)
292  return 0;
293  else if (MI.getOperand(Idx).getImm() == 24)
294  return 1;
295  else if (MI.getOperand(Idx).getImm() == 32)
296  return 2;
297  else if (MI.getOperand(Idx).getImm() == 40)
298  return 3;
299  else
300  assert(0);
301 }
302 
304  const CSKYMCExpr *CSKYExpr = cast<CSKYMCExpr>(Expr);
305 
306  switch (CSKYExpr->getKind()) {
307  default:
308  llvm_unreachable("Unhandled fixup kind!");
327  }
328 }
329 
331  MCContext &Ctx) {
332  return new CSKYMCCodeEmitter(Ctx, MCII);
333 }
334 
335 #include "CSKYGenMCCodeEmitter.inc"
llvm::CSKYMCExpr::VK_CSKY_GOTOFF
@ VK_CSKY_GOTOFF
Definition: CSKYMCExpr.h:28
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:104
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:17
llvm::CSKYMCExpr::VK_CSKY_GOTPC
@ VK_CSKY_GOTPC
Definition: CSKYMCExpr.h:27
llvm::CSKYMCCodeEmitter::expandJBTF
void expandJBTF(const MCInst &MI, raw_ostream &OS, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
Definition: CSKYMCCodeEmitter.cpp:70
llvm::MCOperand::isReg
bool isReg() const
Definition: MCInst.h:61
llvm::MCContext
Context object for machine code objects.
Definition: MCContext.h:74
llvm::MCContext::getRegisterInfo
const MCRegisterInfo * getRegisterInfo() const
Definition: MCContext.h:441
Statistic.h
llvm::createCSKYMCCodeEmitter
MCCodeEmitter * createCSKYMCCodeEmitter(const MCInstrInfo &MCII, MCContext &Ctx)
Definition: CSKYMCCodeEmitter.cpp:330
MCInstBuilder.h
llvm::CSKY::fixup_csky_gotpc
@ fixup_csky_gotpc
Definition: CSKYFixupKinds.h:31
llvm::MCRegisterInfo::getEncodingValue
uint16_t getEncodingValue(MCRegister RegNo) const
Returns the encoding for RegNo.
Definition: MCRegisterInfo.h:553
llvm::CSKY::fixup_csky_got32
@ fixup_csky_got32
Definition: CSKYFixupKinds.h:35
llvm::CSKYMCExpr::VK_CSKY_GOT
@ VK_CSKY_GOT
Definition: CSKYMCExpr.h:25
llvm::MCInst
Instances of this class represent a single low-level machine instruction.
Definition: MCInst.h:184
llvm::CSKY::fixup_csky_got_imm18_scale4
@ fixup_csky_got_imm18_scale4
Definition: CSKYFixupKinds.h:37
llvm::SubDirectoryType::Bin
@ Bin
llvm::MCInstrDesc::getSize
unsigned getSize() const
Return the number of bytes in the encoding of this instruction, or zero if the encoding size cannot b...
Definition: MCInstrDesc.h:622
llvm::MCInstBuilder::addOperand
MCInstBuilder & addOperand(const MCOperand &Op)
Add an operand.
Definition: MCInstBuilder.h:67
llvm::CSKYMCExpr::VK_CSKY_ADDR_HI16
@ VK_CSKY_ADDR_HI16
Definition: CSKYMCExpr.h:22
llvm::CSKYMCCodeEmitter::getBinaryCodeForInstr
uint64_t getBinaryCodeForInstr(const MCInst &MI, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
llvm::CSKY::fixup_csky_plt32
@ fixup_csky_plt32
Definition: CSKYFixupKinds.h:39
llvm::support::little
@ little
Definition: Endian.h:27
llvm::CSKYMCExpr::VK_CSKY_ADDR
@ VK_CSKY_ADDR
Definition: CSKYMCExpr.h:21
MCInstrInfo.h
llvm::MCOperand::getImm
int64_t getImm() const
Definition: MCInst.h:80
llvm::CSKYMCExpr::getKind
VariantKind getKind() const
Definition: CSKYMCExpr.h:51
llvm::CSKYMCCodeEmitter::getRegSeqImmOpValue
unsigned getRegSeqImmOpValue(const MCInst &MI, unsigned Idx, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
Definition: CSKYMCCodeEmitter.cpp:259
llvm::MCInstrDesc
Describe properties that are true of each instruction in the target description file.
Definition: MCInstrDesc.h:197
llvm::AArch64::Fixups
Fixups
Definition: AArch64FixupKinds.h:17
MCSubtargetInfo.h
llvm::MCSubtargetInfo::getFeatureBits
const FeatureBitset & getFeatureBits() const
Definition: MCSubtargetInfo.h:112
llvm::STATISTIC
STATISTIC(NumFunctions, "Total number of functions")
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:54
llvm::CSKYMCExpr::VK_CSKY_PLT
@ VK_CSKY_PLT
Definition: CSKYMCExpr.h:29
llvm::CSKYMCCodeEmitter::getOImmOpValue
unsigned getOImmOpValue(const MCInst &MI, unsigned Idx, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
Definition: CSKYMCCodeEmitter.cpp:30
CSKYMCCodeEmitter.h
llvm::CSKY::fixup_csky_addr_lo16
@ fixup_csky_addr_lo16
Definition: CSKYFixupKinds.h:21
llvm::CSKYMCExpr::VK_CSKY_ADDR_LO16
@ VK_CSKY_ADDR_LO16
Definition: CSKYMCExpr.h:23
llvm::CSKYMCCodeEmitter::getTargetFixup
MCFixupKind getTargetFixup(const MCExpr *Expr) const
Definition: CSKYMCCodeEmitter.cpp:303
llvm::MCOperand::isImm
bool isImm() const
Definition: MCInst.h:62
llvm::CSKYMCExpr
Definition: CSKYMCExpr.h:17
llvm::CSKYMCCodeEmitter::encodeInstruction
void encodeInstruction(const MCInst &Inst, raw_ostream &OS, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const override
EncodeInstruction - Encode the given Inst to bytes on the output stream OS.
Definition: CSKYMCCodeEmitter.cpp:140
MCRegisterInfo.h
llvm::MCInstBuilder
Definition: MCInstBuilder.h:21
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::CSKYMCCodeEmitter
Definition: CSKYMCCodeEmitter.h:25
llvm::CSKY::fixup_csky_addr_hi16
@ fixup_csky_addr_hi16
Definition: CSKYFixupKinds.h:19
CSKYMCTargetDesc.h
llvm::CSKYMCCodeEmitter::getImmJMPIX
unsigned getImmJMPIX(const MCInst &MI, unsigned Idx, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
Definition: CSKYMCCodeEmitter.cpp:288
llvm::CSKYMCCodeEmitter::getRegisterSeqOpValue
unsigned getRegisterSeqOpValue(const MCInst &MI, unsigned Op, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
Definition: CSKYMCCodeEmitter.cpp:275
llvm::CSKY::fixup_csky_gotoff
@ fixup_csky_gotoff
Definition: CSKYFixupKinds.h:33
llvm::CSKY::fixup_csky_plt_imm18_scale4
@ fixup_csky_plt_imm18_scale4
Definition: CSKYFixupKinds.h:41
llvm::MCInstBuilder::addImm
MCInstBuilder & addImm(int64_t Val)
Add a new integer immediate operand.
Definition: MCInstBuilder.h:37
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:143
writeData
static void writeData(uint32_t Bin, unsigned Size, raw_ostream &OS)
Definition: CSKYMCCodeEmitter.cpp:60
uint32_t
llvm::CSKYMCExpr::VK_CSKY_PLT_IMM18_BY4
@ VK_CSKY_PLT_IMM18_BY4
Definition: CSKYMCExpr.h:30
llvm::CSKYMCCodeEmitter::getImmOpValueIDLY
unsigned getImmOpValueIDLY(const MCInst &MI, unsigned Idx, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
Definition: CSKYMCCodeEmitter.cpp:39
llvm::CSKYMCExpr::VK_CSKY_GOT_IMM18_BY4
@ VK_CSKY_GOT_IMM18_BY4
Definition: CSKYMCExpr.h:26
llvm::MCInstrInfo
Interface to description of machine instruction set.
Definition: MCInstrInfo.h:26
EndianStream.h
uint16_t
llvm::MCCodeEmitter
MCCodeEmitter - Generic instruction encoding interface.
Definition: MCCodeEmitter.h:21
llvm::AMDGPU::SendMsg::Op
Op
Definition: SIDefines.h:341
llvm::CSKYMCCodeEmitter::expandNEG
void expandNEG(const MCInst &MI, raw_ostream &OS, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
Definition: CSKYMCCodeEmitter.cpp:96
Casting.h
llvm::CSKYMCCodeEmitter::expandRSUBI
void expandRSUBI(const MCInst &MI, raw_ostream &OS, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
Definition: CSKYMCCodeEmitter.cpp:118
llvm::CSKYMCCodeEmitter::getImmOpValueMSBSize
unsigned getImmOpValueMSBSize(const MCInst &MI, unsigned Idx, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
Definition: CSKYMCCodeEmitter.cpp:50
CSKYMCExpr.h
llvm::MCFixupKind
MCFixupKind
Extensible enumeration to represent the type of a fixup.
Definition: MCFixup.h:21
llvm::SmallVectorImpl
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APFloat.h:42
llvm::MCOperand
Instances of this class represent operands of the MCInst class.
Definition: MCInst.h:36
llvm::CSKY::fixup_csky_addr32
@ fixup_csky_addr32
Definition: CSKYFixupKinds.h:17
llvm::MCInstrInfo::get
const MCInstrDesc & get(unsigned Opcode) const
Return the machine instruction descriptor that corresponds to the specified instruction opcode.
Definition: MCInstrInfo.h:63
llvm::MCSubtargetInfo
Generic base class for all target subtargets.
Definition: MCSubtargetInfo.h:76
llvm::CSKYMCCodeEmitter::getMachineOpValue
unsigned getMachineOpValue(const MCInst &MI, const MCOperand &MO, SmallVectorImpl< MCFixup > &Fixups, const MCSubtargetInfo &STI) const
Definition: CSKYMCCodeEmitter.cpp:245
llvm::MCExpr
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:35
llvm::MCOperand::getReg
unsigned getReg() const
Returns the register number.
Definition: MCInst.h:69