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