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 
23 namespace {
24 class R600MCInstLower : public AMDGPUMCInstLower {
25 public:
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 
34 R600MCInstLower::R600MCInstLower(MCContext &Ctx, const R600Subtarget &ST,
35                                  const AsmPrinter &AP)
36     : AMDGPUMCInstLower(Ctx, ST, AP) {}
37 
38 void 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(MCOp);
44   }
45 }
46 
47 void R600AsmPrinter::emitInstruction(const MachineInstr *MI) {
48   R600_MC::verifyInstructionPredicates(MI->getOpcode(),
49                                        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, Err)) {
56     LLVMContext &C = MI->getParent()->getParent()->getFunction().getContext();
57     C.emitError("Illegal instruction detected: " + Err);
58     MI->print(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(&*I);
66       ++I;
67     }
68   } else {
69     MCInst TmpInst;
70     MCInstLowering.lower(MI, TmpInst);
71     EmitToStreamer(*OutStreamer, TmpInst);
72   }
73 }
74 
75 const 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