xref: /freebsd/contrib/llvm-project/llvm/lib/Target/SPIRV/SPIRVMCInstLower.cpp (revision 700637cbb5e582861067a11aaca4d053546871d2)
1 //=- SPIRVMCInstLower.cpp - Convert SPIR-V MachineInstr to MCInst -*- C++ -*-=//
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 // This file contains code to lower SPIR-V MachineInstrs to their corresponding
10 // MCInst records.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "SPIRVMCInstLower.h"
15 #include "SPIRVModuleAnalysis.h"
16 #include "SPIRVUtils.h"
17 #include "llvm/CodeGen/MachineInstr.h"
18 #include "llvm/IR/Constants.h"
19 
20 using namespace llvm;
21 
lower(const MachineInstr * MI,MCInst & OutMI,SPIRV::ModuleAnalysisInfo * MAI) const22 void SPIRVMCInstLower::lower(const MachineInstr *MI, MCInst &OutMI,
23                              SPIRV::ModuleAnalysisInfo *MAI) const {
24   OutMI.setOpcode(MI->getOpcode());
25   // Propagate previously set flags
26   if (MI->getAsmPrinterFlags() & SPIRV::ASM_PRINTER_WIDTH16)
27     OutMI.setFlags(SPIRV::INST_PRINTER_WIDTH16);
28   const MachineFunction *MF = MI->getMF();
29   for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
30     const MachineOperand &MO = MI->getOperand(i);
31     MCOperand MCOp;
32     switch (MO.getType()) {
33     default:
34       llvm_unreachable("unknown operand type");
35     case MachineOperand::MO_GlobalAddress: {
36       MCRegister FuncReg = MAI->getFuncReg(dyn_cast<Function>(MO.getGlobal()));
37       if (!FuncReg.isValid()) {
38         std::string DiagMsg;
39         raw_string_ostream OS(DiagMsg);
40         MI->print(OS);
41         DiagMsg = "Unknown function in:" + DiagMsg;
42         report_fatal_error(DiagMsg.c_str());
43       }
44       MCOp = MCOperand::createReg(FuncReg);
45       break;
46     }
47     case MachineOperand::MO_MachineBasicBlock:
48       MCOp = MCOperand::createReg(MAI->getOrCreateMBBRegister(*MO.getMBB()));
49       break;
50     case MachineOperand::MO_Register: {
51       MCRegister NewReg = MAI->getRegisterAlias(MF, MO.getReg());
52       MCOp = MCOperand::createReg(NewReg.isValid() ? NewReg
53                                                    : MO.getReg().asMCReg());
54       break;
55     }
56     case MachineOperand::MO_Immediate:
57       if (MI->getOpcode() == SPIRV::OpExtInst && i == 2) {
58         MCRegister Reg = MAI->getExtInstSetReg(MO.getImm());
59         MCOp = MCOperand::createReg(Reg);
60       } else {
61         MCOp = MCOperand::createImm(MO.getImm());
62       }
63       break;
64     case MachineOperand::MO_FPImmediate:
65       MCOp = MCOperand::createDFPImm(
66           MO.getFPImm()->getValueAPF().convertToFloat());
67       break;
68     }
69 
70     OutMI.addOperand(MCOp);
71   }
72 }
73