xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/SPIRV/SPIRVMCInstLower.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
181ad6265SDimitry Andric //=- SPIRVMCInstLower.cpp - Convert SPIR-V MachineInstr to MCInst -*- C++ -*-=//
281ad6265SDimitry Andric //
381ad6265SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
481ad6265SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
581ad6265SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
681ad6265SDimitry Andric //
781ad6265SDimitry Andric //===----------------------------------------------------------------------===//
881ad6265SDimitry Andric //
981ad6265SDimitry Andric // This file contains code to lower SPIR-V MachineInstrs to their corresponding
1081ad6265SDimitry Andric // MCInst records.
1181ad6265SDimitry Andric //
1281ad6265SDimitry Andric //===----------------------------------------------------------------------===//
1381ad6265SDimitry Andric 
1481ad6265SDimitry Andric #include "SPIRVMCInstLower.h"
1581ad6265SDimitry Andric #include "SPIRV.h"
1681ad6265SDimitry Andric #include "SPIRVModuleAnalysis.h"
1781ad6265SDimitry Andric #include "SPIRVUtils.h"
1881ad6265SDimitry Andric #include "llvm/CodeGen/MachineInstr.h"
1981ad6265SDimitry Andric #include "llvm/IR/Constants.h"
2081ad6265SDimitry Andric 
2181ad6265SDimitry Andric using namespace llvm;
2281ad6265SDimitry Andric 
2381ad6265SDimitry Andric void SPIRVMCInstLower::lower(const MachineInstr *MI, MCInst &OutMI,
2481ad6265SDimitry Andric                              SPIRV::ModuleAnalysisInfo *MAI) const {
2581ad6265SDimitry Andric   OutMI.setOpcode(MI->getOpcode());
26*0fca6ea1SDimitry Andric   // Propagate previously set flags
27*0fca6ea1SDimitry Andric   OutMI.setFlags(MI->getAsmPrinterFlags());
2881ad6265SDimitry Andric   const MachineFunction *MF = MI->getMF();
2981ad6265SDimitry Andric   for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
3081ad6265SDimitry Andric     const MachineOperand &MO = MI->getOperand(i);
3181ad6265SDimitry Andric     MCOperand MCOp;
3281ad6265SDimitry Andric     switch (MO.getType()) {
3381ad6265SDimitry Andric     default:
3481ad6265SDimitry Andric       llvm_unreachable("unknown operand type");
3581ad6265SDimitry Andric     case MachineOperand::MO_GlobalAddress: {
36bdd1243dSDimitry Andric       Register FuncReg = MAI->getFuncReg(dyn_cast<Function>(MO.getGlobal()));
37*0fca6ea1SDimitry Andric       if (!FuncReg.isValid()) {
38*0fca6ea1SDimitry Andric         std::string DiagMsg;
39*0fca6ea1SDimitry Andric         raw_string_ostream OS(DiagMsg);
40*0fca6ea1SDimitry Andric         MI->print(OS);
41*0fca6ea1SDimitry Andric         DiagMsg = "Unknown function in:" + DiagMsg;
42*0fca6ea1SDimitry Andric         report_fatal_error(DiagMsg.c_str());
43*0fca6ea1SDimitry Andric       }
4481ad6265SDimitry Andric       MCOp = MCOperand::createReg(FuncReg);
4581ad6265SDimitry Andric       break;
4681ad6265SDimitry Andric     }
4781ad6265SDimitry Andric     case MachineOperand::MO_MachineBasicBlock:
4881ad6265SDimitry Andric       MCOp = MCOperand::createReg(MAI->getOrCreateMBBRegister(*MO.getMBB()));
4981ad6265SDimitry Andric       break;
5081ad6265SDimitry Andric     case MachineOperand::MO_Register: {
5181ad6265SDimitry Andric       Register NewReg = MAI->getRegisterAlias(MF, MO.getReg());
5281ad6265SDimitry Andric       MCOp = MCOperand::createReg(NewReg.isValid() ? NewReg : MO.getReg());
5381ad6265SDimitry Andric       break;
5481ad6265SDimitry Andric     }
5581ad6265SDimitry Andric     case MachineOperand::MO_Immediate:
56fcaf7f86SDimitry Andric       if (MI->getOpcode() == SPIRV::OpExtInst && i == 2) {
57fcaf7f86SDimitry Andric         Register Reg = MAI->getExtInstSetReg(MO.getImm());
58fcaf7f86SDimitry Andric         MCOp = MCOperand::createReg(Reg);
59fcaf7f86SDimitry Andric       } else {
6081ad6265SDimitry Andric         MCOp = MCOperand::createImm(MO.getImm());
61fcaf7f86SDimitry Andric       }
6281ad6265SDimitry Andric       break;
6381ad6265SDimitry Andric     case MachineOperand::MO_FPImmediate:
6481ad6265SDimitry Andric       MCOp = MCOperand::createDFPImm(
6581ad6265SDimitry Andric           MO.getFPImm()->getValueAPF().convertToFloat());
6681ad6265SDimitry Andric       break;
6781ad6265SDimitry Andric     }
6881ad6265SDimitry Andric 
6981ad6265SDimitry Andric     OutMI.addOperand(MCOp);
7081ad6265SDimitry Andric   }
7181ad6265SDimitry Andric }
72