1*81ad6265SDimitry Andric //===- AMDGPUMCInstLower.h - Lower MachineInstr to MCInst ------*- C++ -*--===//
2349cc55cSDimitry Andric //
3349cc55cSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4349cc55cSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5349cc55cSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6349cc55cSDimitry Andric //
7349cc55cSDimitry Andric //===----------------------------------------------------------------------===//
8349cc55cSDimitry Andric //
9349cc55cSDimitry Andric /// \file
10349cc55cSDimitry Andric /// Header of lower AMDGPU MachineInstrs to their corresponding MCInst.
11349cc55cSDimitry Andric //
12349cc55cSDimitry Andric //===----------------------------------------------------------------------===//
13349cc55cSDimitry Andric //
14349cc55cSDimitry Andric 
15349cc55cSDimitry Andric #ifndef LLVM_LIB_TARGET_AMDGPU_AMDGPUMCINSTLOWER_H
16349cc55cSDimitry Andric #define LLVM_LIB_TARGET_AMDGPU_AMDGPUMCINSTLOWER_H
17349cc55cSDimitry Andric 
18349cc55cSDimitry Andric #include "AMDGPUTargetMachine.h"
19349cc55cSDimitry Andric #include "llvm/IR/Constants.h"
20349cc55cSDimitry Andric #include "llvm/Support/Casting.h"
21349cc55cSDimitry Andric 
22349cc55cSDimitry Andric namespace llvm {
23349cc55cSDimitry Andric class AsmPrinter;
24349cc55cSDimitry Andric class MCContext;
25349cc55cSDimitry Andric } // namespace llvm
26349cc55cSDimitry Andric 
27349cc55cSDimitry Andric using namespace llvm;
28349cc55cSDimitry Andric 
29349cc55cSDimitry Andric class AMDGPUMCInstLower {
30349cc55cSDimitry Andric   MCContext &Ctx;
31349cc55cSDimitry Andric   const TargetSubtargetInfo &ST;
32349cc55cSDimitry Andric   const AsmPrinter ≈
33349cc55cSDimitry Andric 
34349cc55cSDimitry Andric public:
35349cc55cSDimitry Andric   AMDGPUMCInstLower(MCContext &ctx, const TargetSubtargetInfo &ST,
36349cc55cSDimitry Andric                     const AsmPrinter &AP);
37349cc55cSDimitry Andric 
38349cc55cSDimitry Andric   bool lowerOperand(const MachineOperand &MO, MCOperand &MCOp) const;
39349cc55cSDimitry Andric 
40349cc55cSDimitry Andric   /// Lower a MachineInstr to an MCInst
41349cc55cSDimitry Andric   void lower(const MachineInstr *MI, MCInst &OutMI) const;
42349cc55cSDimitry Andric };
43349cc55cSDimitry Andric 
44349cc55cSDimitry Andric namespace {
lowerAddrSpaceCast(const TargetMachine & TM,const Constant * CV,MCContext & OutContext)45349cc55cSDimitry Andric static inline const MCExpr *lowerAddrSpaceCast(const TargetMachine &TM,
46349cc55cSDimitry Andric                                                const Constant *CV,
47349cc55cSDimitry Andric                                                MCContext &OutContext) {
48349cc55cSDimitry Andric   // TargetMachine does not support llvm-style cast. Use C++-style cast.
49349cc55cSDimitry Andric   // This is safe since TM is always of type AMDGPUTargetMachine or its
50349cc55cSDimitry Andric   // derived class.
51349cc55cSDimitry Andric   auto &AT = static_cast<const AMDGPUTargetMachine &>(TM);
52349cc55cSDimitry Andric   auto *CE = dyn_cast<ConstantExpr>(CV);
53349cc55cSDimitry Andric 
54349cc55cSDimitry Andric   // Lower null pointers in private and local address space.
55349cc55cSDimitry Andric   // Clang generates addrspacecast for null pointers in private and local
56349cc55cSDimitry Andric   // address space, which needs to be lowered.
57349cc55cSDimitry Andric   if (CE && CE->getOpcode() == Instruction::AddrSpaceCast) {
58349cc55cSDimitry Andric     auto Op = CE->getOperand(0);
59349cc55cSDimitry Andric     auto SrcAddr = Op->getType()->getPointerAddressSpace();
60349cc55cSDimitry Andric     if (Op->isNullValue() && AT.getNullPointerValue(SrcAddr) == 0) {
61349cc55cSDimitry Andric       auto DstAddr = CE->getType()->getPointerAddressSpace();
62349cc55cSDimitry Andric       return MCConstantExpr::create(AT.getNullPointerValue(DstAddr),
63349cc55cSDimitry Andric                                     OutContext);
64349cc55cSDimitry Andric     }
65349cc55cSDimitry Andric   }
66349cc55cSDimitry Andric   return nullptr;
67349cc55cSDimitry Andric }
68349cc55cSDimitry Andric } // namespace
69349cc55cSDimitry Andric #endif // LLVM_LIB_TARGET_AMDGPU_AMDGPUMCINSTLOWER_H
70