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