xref: /freebsd-src/contrib/llvm-project/llvm/lib/Target/SPIRV/SPIRVMCInstLower.cpp (revision bdd1243df58e60e85101c09001d9812a789b6bc4)
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());
2681ad6265SDimitry Andric   const MachineFunction *MF = MI->getMF();
2781ad6265SDimitry Andric   for (unsigned i = 0, e = MI->getNumOperands(); i != e; ++i) {
2881ad6265SDimitry Andric     const MachineOperand &MO = MI->getOperand(i);
2981ad6265SDimitry Andric     MCOperand MCOp;
3081ad6265SDimitry Andric     switch (MO.getType()) {
3181ad6265SDimitry Andric     default:
3281ad6265SDimitry Andric       llvm_unreachable("unknown operand type");
3381ad6265SDimitry Andric     case MachineOperand::MO_GlobalAddress: {
34*bdd1243dSDimitry Andric       Register FuncReg = MAI->getFuncReg(dyn_cast<Function>(MO.getGlobal()));
3581ad6265SDimitry Andric       assert(FuncReg.isValid() && "Cannot find function Id");
3681ad6265SDimitry Andric       MCOp = MCOperand::createReg(FuncReg);
3781ad6265SDimitry Andric       break;
3881ad6265SDimitry Andric     }
3981ad6265SDimitry Andric     case MachineOperand::MO_MachineBasicBlock:
4081ad6265SDimitry Andric       MCOp = MCOperand::createReg(MAI->getOrCreateMBBRegister(*MO.getMBB()));
4181ad6265SDimitry Andric       break;
4281ad6265SDimitry Andric     case MachineOperand::MO_Register: {
4381ad6265SDimitry Andric       Register NewReg = MAI->getRegisterAlias(MF, MO.getReg());
4481ad6265SDimitry Andric       MCOp = MCOperand::createReg(NewReg.isValid() ? NewReg : MO.getReg());
4581ad6265SDimitry Andric       break;
4681ad6265SDimitry Andric     }
4781ad6265SDimitry Andric     case MachineOperand::MO_Immediate:
48fcaf7f86SDimitry Andric       if (MI->getOpcode() == SPIRV::OpExtInst && i == 2) {
49fcaf7f86SDimitry Andric         Register Reg = MAI->getExtInstSetReg(MO.getImm());
50fcaf7f86SDimitry Andric         MCOp = MCOperand::createReg(Reg);
51fcaf7f86SDimitry Andric       } else {
5281ad6265SDimitry Andric         MCOp = MCOperand::createImm(MO.getImm());
53fcaf7f86SDimitry Andric       }
5481ad6265SDimitry Andric       break;
5581ad6265SDimitry Andric     case MachineOperand::MO_FPImmediate:
5681ad6265SDimitry Andric       MCOp = MCOperand::createDFPImm(
5781ad6265SDimitry Andric           MO.getFPImm()->getValueAPF().convertToFloat());
5881ad6265SDimitry Andric       break;
5981ad6265SDimitry Andric     }
6081ad6265SDimitry Andric 
6181ad6265SDimitry Andric     OutMI.addOperand(MCOp);
6281ad6265SDimitry Andric   }
6381ad6265SDimitry Andric }
64