1e8d8bef9SDimitry Andric //===- AArch64GlobalISelUtils.h ----------------------------------*- C++ -*-==// 2e8d8bef9SDimitry Andric // 3e8d8bef9SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4e8d8bef9SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5e8d8bef9SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6e8d8bef9SDimitry Andric // 7e8d8bef9SDimitry Andric //===----------------------------------------------------------------------===// 8e8d8bef9SDimitry Andric /// \file APIs for AArch64-specific helper functions used in the GlobalISel 9e8d8bef9SDimitry Andric /// pipeline. 10e8d8bef9SDimitry Andric //===----------------------------------------------------------------------===// 11e8d8bef9SDimitry Andric 12e8d8bef9SDimitry Andric #ifndef LLVM_LIB_TARGET_AARCH64_GISEL_AARCH64GLOBALISELUTILS_H 13e8d8bef9SDimitry Andric #define LLVM_LIB_TARGET_AARCH64_GISEL_AARCH64GLOBALISELUTILS_H 14fe6060f1SDimitry Andric #include "MCTargetDesc/AArch64AddressingModes.h" 15fe6060f1SDimitry Andric #include "Utils/AArch64BaseInfo.h" 16fe6060f1SDimitry Andric #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h" 17fe6060f1SDimitry Andric #include "llvm/CodeGen/GlobalISel/Utils.h" 18fe6060f1SDimitry Andric #include "llvm/CodeGen/Register.h" 19fe6060f1SDimitry Andric #include "llvm/IR/InstrTypes.h" 20e8d8bef9SDimitry Andric #include <cstdint> 21e8d8bef9SDimitry Andric 22e8d8bef9SDimitry Andric namespace llvm { 23fe6060f1SDimitry Andric 24e8d8bef9SDimitry Andric namespace AArch64GISelUtils { 25e8d8bef9SDimitry Andric 26e8d8bef9SDimitry Andric /// \returns true if \p C is a legal immediate operand for an arithmetic 27e8d8bef9SDimitry Andric /// instruction. 28e8d8bef9SDimitry Andric constexpr bool isLegalArithImmed(const uint64_t C) { 29e8d8bef9SDimitry Andric return (C >> 12 == 0) || ((C & 0xFFFULL) == 0 && C >> 24 == 0); 30e8d8bef9SDimitry Andric } 31e8d8bef9SDimitry Andric 32fe6060f1SDimitry Andric /// \returns A value when \p MI is a vector splat of a Register or constant. 33fe6060f1SDimitry Andric /// Checks for generic opcodes and AArch64-specific generic opcodes. 34bdd1243dSDimitry Andric std::optional<RegOrConstant> 35bdd1243dSDimitry Andric getAArch64VectorSplat(const MachineInstr &MI, const MachineRegisterInfo &MRI); 36fe6060f1SDimitry Andric 37fe6060f1SDimitry Andric /// \returns A value when \p MI is a constant vector splat. 38fe6060f1SDimitry Andric /// Checks for generic opcodes and AArch64-specific generic opcodes. 39bdd1243dSDimitry Andric std::optional<int64_t> 40bdd1243dSDimitry Andric getAArch64VectorSplatScalar(const MachineInstr &MI, 41fe6060f1SDimitry Andric const MachineRegisterInfo &MRI); 42fe6060f1SDimitry Andric 43fe6060f1SDimitry Andric /// \returns true if \p MaybeSub and \p Pred are part of a CMN tree for an 44fe6060f1SDimitry Andric /// integer compare. 45fe6060f1SDimitry Andric bool isCMN(const MachineInstr *MaybeSub, const CmpInst::Predicate &Pred, 46fe6060f1SDimitry Andric const MachineRegisterInfo &MRI); 47fe6060f1SDimitry Andric 48fe6060f1SDimitry Andric /// Replace a G_MEMSET with a value of 0 with a G_BZERO instruction if it is 49fe6060f1SDimitry Andric /// supported and beneficial to do so. 50fe6060f1SDimitry Andric /// 51fe6060f1SDimitry Andric /// \note This only applies on Darwin. 52fe6060f1SDimitry Andric /// 53fe6060f1SDimitry Andric /// \returns true if \p MI was replaced with a G_BZERO. 54fe6060f1SDimitry Andric bool tryEmitBZero(MachineInstr &MI, MachineIRBuilder &MIRBuilder, bool MinSize); 55fe6060f1SDimitry Andric 56*0fca6ea1SDimitry Andric /// Analyze a ptrauth discriminator value to try to find the constant integer 57*0fca6ea1SDimitry Andric /// and address parts, cracking a ptrauth_blend intrinsic if there is one. 58*0fca6ea1SDimitry Andric /// \returns integer/address disc. parts, with NoRegister if no address disc. 59*0fca6ea1SDimitry Andric std::tuple<uint16_t, Register> 60*0fca6ea1SDimitry Andric extractPtrauthBlendDiscriminators(Register Disc, MachineRegisterInfo &MRI); 61*0fca6ea1SDimitry Andric 62fe6060f1SDimitry Andric /// Find the AArch64 condition codes necessary to represent \p P for a scalar 63fe6060f1SDimitry Andric /// floating point comparison. 64fe6060f1SDimitry Andric /// 65fe6060f1SDimitry Andric /// \param [out] CondCode is the first condition code. 66fe6060f1SDimitry Andric /// \param [out] CondCode2 is the second condition code if necessary. 67fe6060f1SDimitry Andric /// AArch64CC::AL otherwise. 68fe6060f1SDimitry Andric void changeFCMPPredToAArch64CC(const CmpInst::Predicate P, 69fe6060f1SDimitry Andric AArch64CC::CondCode &CondCode, 70fe6060f1SDimitry Andric AArch64CC::CondCode &CondCode2); 71fe6060f1SDimitry Andric 72fe6060f1SDimitry Andric /// Find the AArch64 condition codes necessary to represent \p P for a vector 73fe6060f1SDimitry Andric /// floating point comparison. 74fe6060f1SDimitry Andric /// 75fe6060f1SDimitry Andric /// \param [out] CondCode - The first condition code. 76fe6060f1SDimitry Andric /// \param [out] CondCode2 - The second condition code if necessary. 77fe6060f1SDimitry Andric /// AArch64CC::AL otherwise. 78fe6060f1SDimitry Andric /// \param [out] Invert - True if the comparison must be inverted with a NOT. 79fe6060f1SDimitry Andric void changeVectorFCMPPredToAArch64CC(const CmpInst::Predicate P, 80fe6060f1SDimitry Andric AArch64CC::CondCode &CondCode, 81fe6060f1SDimitry Andric AArch64CC::CondCode &CondCode2, 82fe6060f1SDimitry Andric bool &Invert); 83fe6060f1SDimitry Andric 84e8d8bef9SDimitry Andric } // namespace AArch64GISelUtils 85e8d8bef9SDimitry Andric } // namespace llvm 86e8d8bef9SDimitry Andric 87e8d8bef9SDimitry Andric #endif 88