147d6274dSDaniil Fukalov //===- R600MCInstLower.cpp - Lower R600 MachineInstr to an MCInst ---------===//
247d6274dSDaniil Fukalov //
347d6274dSDaniil Fukalov // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
447d6274dSDaniil Fukalov // See https://llvm.org/LICENSE.txt for license information.
547d6274dSDaniil Fukalov // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
647d6274dSDaniil Fukalov //
747d6274dSDaniil Fukalov //===----------------------------------------------------------------------===//
847d6274dSDaniil Fukalov //
947d6274dSDaniil Fukalov /// \file
1047d6274dSDaniil Fukalov /// Code to lower R600 MachineInstrs to their corresponding MCInst.
1147d6274dSDaniil Fukalov //
1247d6274dSDaniil Fukalov //===----------------------------------------------------------------------===//
1347d6274dSDaniil Fukalov //
1447d6274dSDaniil Fukalov
1547d6274dSDaniil Fukalov #include "AMDGPUMCInstLower.h"
16*3e0bf1c7SDavid Green #include "MCTargetDesc/R600MCTargetDesc.h"
1747d6274dSDaniil Fukalov #include "R600AsmPrinter.h"
1847d6274dSDaniil Fukalov #include "R600Subtarget.h"
1947d6274dSDaniil Fukalov #include "llvm/CodeGen/MachineOperand.h"
2047d6274dSDaniil Fukalov #include "llvm/MC/MCContext.h"
2147d6274dSDaniil Fukalov #include "llvm/MC/MCExpr.h"
2247d6274dSDaniil Fukalov
2347d6274dSDaniil Fukalov class R600MCInstLower : public AMDGPUMCInstLower {
2447d6274dSDaniil Fukalov public:
2547d6274dSDaniil Fukalov R600MCInstLower(MCContext &ctx, const R600Subtarget &ST,
2647d6274dSDaniil Fukalov const AsmPrinter &AP);
2747d6274dSDaniil Fukalov
2847d6274dSDaniil Fukalov /// Lower a MachineInstr to an MCInst
2947d6274dSDaniil Fukalov void lower(const MachineInstr *MI, MCInst &OutMI) const;
3047d6274dSDaniil Fukalov };
3147d6274dSDaniil Fukalov
R600MCInstLower(MCContext & Ctx,const R600Subtarget & ST,const AsmPrinter & AP)3247d6274dSDaniil Fukalov R600MCInstLower::R600MCInstLower(MCContext &Ctx, const R600Subtarget &ST,
3347d6274dSDaniil Fukalov const AsmPrinter &AP)
3447d6274dSDaniil Fukalov : AMDGPUMCInstLower(Ctx, ST, AP) {}
3547d6274dSDaniil Fukalov
lower(const MachineInstr * MI,MCInst & OutMI) const3647d6274dSDaniil Fukalov void R600MCInstLower::lower(const MachineInstr *MI, MCInst &OutMI) const {
3747d6274dSDaniil Fukalov OutMI.setOpcode(MI->getOpcode());
3847d6274dSDaniil Fukalov for (const MachineOperand &MO : MI->explicit_operands()) {
3947d6274dSDaniil Fukalov MCOperand MCOp;
4047d6274dSDaniil Fukalov lowerOperand(MO, MCOp);
4147d6274dSDaniil Fukalov OutMI.addOperand(MCOp);
4247d6274dSDaniil Fukalov }
4347d6274dSDaniil Fukalov }
4447d6274dSDaniil Fukalov
emitInstruction(const MachineInstr * MI)4547d6274dSDaniil Fukalov void R600AsmPrinter::emitInstruction(const MachineInstr *MI) {
46*3e0bf1c7SDavid Green R600_MC::verifyInstructionPredicates(MI->getOpcode(),
47*3e0bf1c7SDavid Green getSubtargetInfo().getFeatureBits());
48*3e0bf1c7SDavid Green
4947d6274dSDaniil Fukalov const R600Subtarget &STI = MF->getSubtarget<R600Subtarget>();
5047d6274dSDaniil Fukalov R600MCInstLower MCInstLowering(OutContext, STI, *this);
5147d6274dSDaniil Fukalov
5247d6274dSDaniil Fukalov StringRef Err;
5347d6274dSDaniil Fukalov if (!STI.getInstrInfo()->verifyInstruction(*MI, Err)) {
5447d6274dSDaniil Fukalov LLVMContext &C = MI->getParent()->getParent()->getFunction().getContext();
5547d6274dSDaniil Fukalov C.emitError("Illegal instruction detected: " + Err);
5647d6274dSDaniil Fukalov MI->print(errs());
5747d6274dSDaniil Fukalov }
5847d6274dSDaniil Fukalov
5947d6274dSDaniil Fukalov if (MI->isBundle()) {
6047d6274dSDaniil Fukalov const MachineBasicBlock *MBB = MI->getParent();
6147d6274dSDaniil Fukalov MachineBasicBlock::const_instr_iterator I = ++MI->getIterator();
6247d6274dSDaniil Fukalov while (I != MBB->instr_end() && I->isInsideBundle()) {
6347d6274dSDaniil Fukalov emitInstruction(&*I);
6447d6274dSDaniil Fukalov ++I;
6547d6274dSDaniil Fukalov }
6647d6274dSDaniil Fukalov } else {
6747d6274dSDaniil Fukalov MCInst TmpInst;
6847d6274dSDaniil Fukalov MCInstLowering.lower(MI, TmpInst);
6947d6274dSDaniil Fukalov EmitToStreamer(*OutStreamer, TmpInst);
7047d6274dSDaniil Fukalov }
7147d6274dSDaniil Fukalov }
7247d6274dSDaniil Fukalov
lowerConstant(const Constant * CV)7347d6274dSDaniil Fukalov const MCExpr *R600AsmPrinter::lowerConstant(const Constant *CV) {
7447d6274dSDaniil Fukalov if (const MCExpr *E = lowerAddrSpaceCast(TM, CV, OutContext))
7547d6274dSDaniil Fukalov return E;
7647d6274dSDaniil Fukalov return AsmPrinter::lowerConstant(CV);
7747d6274dSDaniil Fukalov }
78