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/ADT/Optional.h"
17 #include "llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
18 #include "llvm/CodeGen/GlobalISel/Utils.h"
19 #include "llvm/CodeGen/Register.h"
20 #include "llvm/IR/InstrTypes.h"
21 #include <cstdint>
22 
23 namespace llvm {
24 
25 namespace AArch64GISelUtils {
26 
27 /// \returns true if \p C is a legal immediate operand for an arithmetic
28 /// instruction.
29 constexpr bool isLegalArithImmed(const uint64_t C) {
30   return (C >> 12 == 0) || ((C & 0xFFFULL) == 0 && C >> 24 == 0);
31 }
32 
33 /// \returns A value when \p MI is a vector splat of a Register or constant.
34 /// Checks for generic opcodes and AArch64-specific generic opcodes.
35 Optional<RegOrConstant> getAArch64VectorSplat(const MachineInstr &MI,
36                                               const MachineRegisterInfo &MRI);
37 
38 /// \returns A value when \p MI is a constant vector splat.
39 /// Checks for generic opcodes and AArch64-specific generic opcodes.
40 Optional<int64_t> 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 /// Find the AArch64 condition codes necessary to represent \p P for a scalar
57 /// floating point comparison.
58 ///
59 /// \param [out] CondCode is the first condition code.
60 /// \param [out] CondCode2 is the second condition code if necessary.
61 /// AArch64CC::AL otherwise.
62 void changeFCMPPredToAArch64CC(const CmpInst::Predicate P,
63                                AArch64CC::CondCode &CondCode,
64                                AArch64CC::CondCode &CondCode2);
65 
66 /// Find the AArch64 condition codes necessary to represent \p P for a vector
67 /// floating point comparison.
68 ///
69 /// \param [out] CondCode - The first condition code.
70 /// \param [out] CondCode2 - The second condition code if necessary.
71 /// AArch64CC::AL otherwise.
72 /// \param [out] Invert - True if the comparison must be inverted with a NOT.
73 void changeVectorFCMPPredToAArch64CC(const CmpInst::Predicate P,
74                                      AArch64CC::CondCode &CondCode,
75                                      AArch64CC::CondCode &CondCode2,
76                                      bool &Invert);
77 
78 } // namespace AArch64GISelUtils
79 } // namespace llvm
80 
81 #endif
82