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