xref: /freebsd/contrib/llvm-project/llvm/lib/Target/SPIRV/SPIRVMCInstLower.cpp (revision b64c5a0ace59af62eff52bfe110a521dc73c937b)
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 "SPIRV.h"
16 #include "SPIRVModuleAnalysis.h"
17 #include "SPIRVUtils.h"
18 #include "llvm/CodeGen/MachineInstr.h"
19 #include "llvm/IR/Constants.h"
20 
21 using namespace llvm;
22 
23 void SPIRVMCInstLower::lower(const MachineInstr *MI, MCInst &OutMI,
24                              SPIRV::ModuleAnalysisInfo *MAI) const {
25   OutMI.setOpcode(MI->getOpcode());
26   // Propagate previously set flags
27   OutMI.setFlags(MI->getAsmPrinterFlags());
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       Register 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       Register NewReg = MAI->getRegisterAlias(MF, MO.getReg());
52       MCOp = MCOperand::createReg(NewReg.isValid() ? NewReg : MO.getReg());
53       break;
54     }
55     case MachineOperand::MO_Immediate:
56       if (MI->getOpcode() == SPIRV::OpExtInst && i == 2) {
57         Register Reg = MAI->getExtInstSetReg(MO.getImm());
58         MCOp = MCOperand::createReg(Reg);
59       } else {
60         MCOp = MCOperand::createImm(MO.getImm());
61       }
62       break;
63     case MachineOperand::MO_FPImmediate:
64       MCOp = MCOperand::createDFPImm(
65           MO.getFPImm()->getValueAPF().convertToFloat());
66       break;
67     }
68 
69     OutMI.addOperand(MCOp);
70   }
71 }
72