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 
lower(const MachineInstr * MI,MCInst & OutMI,SPIRV::ModuleAnalysisInfo * MAI) const23 void SPIRVMCInstLower::lower(const MachineInstr *MI, MCInst &OutMI,
24                              SPIRV::ModuleAnalysisInfo *MAI) const {
25   OutMI.setOpcode(MI->getOpcode());
26   const MachineFunction *MF = MI->getMF();
27   for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
28     const MachineOperand &MO = MI->getOperand(i);
29     MCOperand MCOp;
30     switch (MO.getType()) {
31     default:
32       llvm_unreachable("unknown operand type");
33     case MachineOperand::MO_GlobalAddress: {
34       Register FuncReg = MAI->getFuncReg(dyn_cast<Function>(MO.getGlobal()));
35       assert(FuncReg.isValid() && "Cannot find function Id");
36       MCOp = MCOperand::createReg(FuncReg);
37       break;
38     }
39     case MachineOperand::MO_MachineBasicBlock:
40       MCOp = MCOperand::createReg(MAI->getOrCreateMBBRegister(*MO.getMBB()));
41       break;
42     case MachineOperand::MO_Register: {
43       Register NewReg = MAI->getRegisterAlias(MF, MO.getReg());
44       MCOp = MCOperand::createReg(NewReg.isValid() ? NewReg : MO.getReg());
45       break;
46     }
47     case MachineOperand::MO_Immediate:
48       if (MI->getOpcode() == SPIRV::OpExtInst && i == 2) {
49         Register Reg = MAI->getExtInstSetReg(MO.getImm());
50         MCOp = MCOperand::createReg(Reg);
51       } else {
52         MCOp = MCOperand::createImm(MO.getImm());
53       }
54       break;
55     case MachineOperand::MO_FPImmediate:
56       MCOp = MCOperand::createDFPImm(
57           MO.getFPImm()->getValueAPF().convertToFloat());
58       break;
59     }
60 
61     OutMI.addOperand(MCOp);
62   }
63 }
64