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(Op: MCOp); |
44 | } |
45 | } |
46 | |
47 | void 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 | |
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 | |