1//===- R600MCInstLower.cpp - Lower R600 MachineInstr to an MCInst ---------===//
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/// \file
10/// Code to lower R600 MachineInstrs to their corresponding MCInst.
11//
12//===----------------------------------------------------------------------===//
13//
14
15#include "AMDGPUMCInstLower.h"
16#include "MCTargetDesc/R600MCTargetDesc.h"
17#include "R600AsmPrinter.h"
18#include "R600Subtarget.h"
19#include "llvm/CodeGen/MachineOperand.h"
20#include "llvm/MC/MCContext.h"
21#include "llvm/MC/MCExpr.h"
22
23namespace {
24class R600MCInstLower : public AMDGPUMCInstLower {
25public:
26 R600MCInstLower(MCContext &ctx, const R600Subtarget &ST,
27 const AsmPrinter &AP);
28
29 /// Lower a MachineInstr to an MCInst
30 void lower(const MachineInstr *MI, MCInst &OutMI) const;
31};
32} // namespace
33
34R600MCInstLower::R600MCInstLower(MCContext &Ctx, const R600Subtarget &ST,
35 const AsmPrinter &AP)
36 : AMDGPUMCInstLower(Ctx, ST, AP) {}
37
38void R600MCInstLower::lower(const MachineInstr *MI, MCInst &OutMI) const {
39 OutMI.setOpcode(MI->getOpcode());
40 for (const MachineOperand &MO : MI->explicit_operands()) {
41 MCOperand MCOp;
42 lowerOperand(MO, MCOp);
43 OutMI.addOperand(Op: MCOp);
44 }
45}
46
47void R600AsmPrinter::emitInstruction(const MachineInstr *MI) {
48 R600_MC::verifyInstructionPredicates(Opcode: MI->getOpcode(),
49 Features: getSubtargetInfo().getFeatureBits());
50
51 const R600Subtarget &STI = MF->getSubtarget<R600Subtarget>();
52 R600MCInstLower MCInstLowering(OutContext, STI, *this);
53
54 StringRef Err;
55 if (!STI.getInstrInfo()->verifyInstruction(MI: *MI, ErrInfo&: Err)) {
56 LLVMContext &C = MI->getParent()->getParent()->getFunction().getContext();
57 C.emitError(ErrorStr: "Illegal instruction detected: " + Err);
58 MI->print(OS&: errs());
59 }
60
61 if (MI->isBundle()) {
62 const MachineBasicBlock *MBB = MI->getParent();
63 MachineBasicBlock::const_instr_iterator I = ++MI->getIterator();
64 while (I != MBB->instr_end() && I->isInsideBundle()) {
65 emitInstruction(MI: &*I);
66 ++I;
67 }
68 } else {
69 MCInst TmpInst;
70 MCInstLowering.lower(MI, OutMI&: TmpInst);
71 EmitToStreamer(S&: *OutStreamer, Inst: TmpInst);
72 }
73}
74
75const MCExpr *R600AsmPrinter::lowerConstant(const Constant *CV) {
76 if (const MCExpr *E = lowerAddrSpaceCast(TM, CV, OutContext))
77 return E;
78 return AsmPrinter::lowerConstant(CV);
79}
80