xref: /freebsd/contrib/llvm-project/llvm/lib/Target/AMDGPU/R600MCInstLower.cpp (revision 5956d97f4b3204318ceb6aa9c77bd0bc6ea87a41)
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 "R600AsmPrinter.h"
17 #include "R600Subtarget.h"
18 #include "llvm/CodeGen/MachineOperand.h"
19 #include "llvm/MC/MCContext.h"
20 #include "llvm/MC/MCExpr.h"
21 
22 class R600MCInstLower : public AMDGPUMCInstLower {
23 public:
24   R600MCInstLower(MCContext &ctx, const R600Subtarget &ST,
25                   const AsmPrinter &AP);
26 
27   /// Lower a MachineInstr to an MCInst
28   void lower(const MachineInstr *MI, MCInst &OutMI) const;
29 };
30 
31 R600MCInstLower::R600MCInstLower(MCContext &Ctx, const R600Subtarget &ST,
32                                  const AsmPrinter &AP)
33     : AMDGPUMCInstLower(Ctx, ST, AP) {}
34 
35 void R600MCInstLower::lower(const MachineInstr *MI, MCInst &OutMI) const {
36   OutMI.setOpcode(MI->getOpcode());
37   for (const MachineOperand &MO : MI->explicit_operands()) {
38     MCOperand MCOp;
39     lowerOperand(MO, MCOp);
40     OutMI.addOperand(MCOp);
41   }
42 }
43 
44 void R600AsmPrinter::emitInstruction(const MachineInstr *MI) {
45   const R600Subtarget &STI = MF->getSubtarget<R600Subtarget>();
46   R600MCInstLower MCInstLowering(OutContext, STI, *this);
47 
48   StringRef Err;
49   if (!STI.getInstrInfo()->verifyInstruction(*MI, Err)) {
50     LLVMContext &C = MI->getParent()->getParent()->getFunction().getContext();
51     C.emitError("Illegal instruction detected: " + Err);
52     MI->print(errs());
53   }
54 
55   if (MI->isBundle()) {
56     const MachineBasicBlock *MBB = MI->getParent();
57     MachineBasicBlock::const_instr_iterator I = ++MI->getIterator();
58     while (I != MBB->instr_end() && I->isInsideBundle()) {
59       emitInstruction(&*I);
60       ++I;
61     }
62   } else {
63     MCInst TmpInst;
64     MCInstLowering.lower(MI, TmpInst);
65     EmitToStreamer(*OutStreamer, TmpInst);
66   }
67 }
68 
69 const MCExpr *R600AsmPrinter::lowerConstant(const Constant *CV) {
70   if (const MCExpr *E = lowerAddrSpaceCast(TM, CV, OutContext))
71     return E;
72   return AsmPrinter::lowerConstant(CV);
73 }
74