29  return ST.isTargetAEABI() || ST.isTargetGNUAEABI() || ST.isTargetMuslAEABI();
 
 
   44  if (ST.isThumb1Only()) {
 
   46    LegacyInfo.computeTables();
 
   47    verify(*ST.getInstrInfo());
 
   52      .legalForCartesianProduct({s8, s16, s32}, {s1, s8, s16});
 
   58      .clampScalar(0, s32, s32);
 
   70    .legalFor({{s32, s32}})
 
   74  bool HasHWDivide = (!ST.isThumb() && ST.hasDivideInARMMode()) ||
 
   75                     (ST.isThumb() && ST.hasDivideInThumbMode());
 
   79        .clampScalar(0, s32, s32);
 
   83        .clampScalar(0, s32, s32);
 
   88    REMBuilder.lowerFor({s32});
 
   90    REMBuilder.customFor({s32});
 
   92    REMBuilder.libcallFor({s32});
 
  103      .clampScalar(0, s32, s32);
 
  118                               .legalForTypesWithMemDesc({{s8, p0, s8, 8},
 
  122                               .unsupportedIfMemSizeNotPow2();
 
  138  if (!ST.useSoftFloat() && ST.hasVFP2Base()) {
 
  140        {G_FADD, G_FSUB, G_FMUL, G_FDIV, G_FCONSTANT, G_FNEG})
 
  141        .legalFor({s32, s64});
 
  158        .legalForCartesianProduct({s32}, {s32, s64});
 
  160        .legalForCartesianProduct({s32, s64}, {s32});
 
  169        .libcallFor({s32, s64});
 
  181      setFCmpLibcallsAEABI();
 
  183      setFCmpLibcallsGNU();
 
  189        .libcallForCartesianProduct({s32}, {s32, s64});
 
  191        .libcallForCartesianProduct({s32, s64}, {s32});
 
  200  LoadStoreBuilder.
lower();
 
  202  if (!ST.useSoftFloat() && ST.hasVFP4Base())
 
  209  if (ST.hasV5TOps() && !ST.isThumb1Only()) {
 
  212        .clampScalar(1, s32, s32)
 
  216        .clampScalar(1, s32, s32)
 
  221        .clampScalar(1, s32, s32)
 
  225        .clampScalar(1, s32, s32)
 
  229  LegacyInfo.computeTables();
 
  230  verify(*ST.getInstrInfo());
 
 
  233void ARMLegalizerInfo::setFCmpLibcallsAEABI() {
 
  289void ARMLegalizerInfo::setFCmpLibcallsGNU() {
 
  329ARMLegalizerInfo::FCmpLibcallsList
 
  331                                  unsigned Size)
 const {
 
  348  switch (
MI.getOpcode()) {
 
  353    Register OriginalResult = 
MI.getOperand(0).getReg();
 
  354    auto Size = 
MRI.getType(OriginalResult).getSizeInBits();
 
  359        MI.getOpcode() == G_SREM ? RTLIB::SDIVREM_I32 : RTLIB::UDIVREM_I32;
 
  369                                {{
MI.getOperand(1).getReg(), ArgTy, 0},
 
  370                                 {
MI.getOperand(2).getReg(), ArgTy, 0}},
 
  378               MRI.getType(
MI.getOperand(3).getReg()) &&
 
  379           "Mismatched operands for G_FCMP");
 
  380    auto OpSize = 
MRI.getType(
MI.getOperand(2).getReg()).getSizeInBits();
 
  382    auto OriginalResult = 
MI.getOperand(0).getReg();
 
  385    auto Libcalls = getFCmpLibcalls(Predicate, OpSize);
 
  387    if (Libcalls.empty()) {
 
  390             "Predicate needs libcalls, but none specified");
 
  393      MI.eraseFromParent();
 
  397    assert((OpSize == 32 || OpSize == 64) && 
"Unsupported operand size");
 
  402    for (
auto Libcall : Libcalls) {
 
  403      auto LibcallResult = 
MRI.createGenericVirtualRegister(
LLT::scalar(32));
 
  405                                  {LibcallResult, RetTy, 0},
 
  406                                  {{MI.getOperand(2).getReg(), ArgTy, 0},
 
  407                                   {MI.getOperand(3).getReg(), ArgTy, 0}},
 
  413      auto ProcessedResult =
 
  416              : 
MRI.createGenericVirtualRegister(
MRI.getType(OriginalResult));
 
  425        MIRBuilder.
buildTrunc(ProcessedResult, LibcallResult);
 
  430        MIRBuilder.
buildICmp(ResultPred, ProcessedResult, LibcallResult, Zero);
 
  432      Results.push_back(ProcessedResult);
 
  436      assert(
Results.size() == 2 && 
"Unexpected number of results");
 
  451        MI.getOperand(1).getFPImm()->getValueAPF().bitcastToAPInt();
 
  453                             *ConstantInt::get(Ctx, AsInteger));
 
  459    auto FPEnv = 
MRI.createGenericVirtualRegister(FPEnvTy);
 
  463    auto StatusBits = MIRBuilder.
buildAnd(FPEnvTy, FPEnv, StatusBitMask);
 
  464    auto NotStatusBitMask =
 
  466    auto FPModeBits = MIRBuilder.
buildAnd(FPEnvTy, Modes, NotStatusBitMask);
 
  467    auto NewFPSCR = MIRBuilder.
buildOr(FPEnvTy, StatusBits, FPModeBits);
 
  471  case G_RESET_FPMODE: {
 
  478    auto NewFPSCR = MIRBuilder.
buildAnd(FPEnvTy, FPEnv, NotModeBitMask);
 
  484  MI.eraseFromParent();
 
 
unsigned const MachineRegisterInfo * MRI
 
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
 
This file describes how to lower LLVM calls to machine code calls.
 
static bool AEABI(const ARMSubtarget &ST)
 
This file declares the targeting of the Machinelegalizer class for ARM.
 
Function Alias Analysis Results
 
Implement a low-level type suitable for MachineInstr level instruction selection.
 
This file declares the MachineIRBuilder class.
 
ARMLegalizerInfo(const ARMSubtarget &ST)
 
bool legalizeCustom(LegalizerHelper &Helper, MachineInstr &MI, LostDebugLocObserver &LocObserver) const override
Called for instructions with the Custom LegalizationAction.
 
Predicate
This enumeration lists the possible predicates for CmpInst subclasses.
 
@ FCMP_OEQ
0 0 0 1 True if ordered and equal
 
@ FCMP_TRUE
1 1 1 1 Always true (always folded)
 
@ ICMP_SLT
signed less than
 
@ ICMP_SLE
signed less or equal
 
@ FCMP_OLT
0 1 0 0 True if ordered and less than
 
@ FCMP_ULE
1 1 0 1 True if unordered, less than, or equal
 
@ FCMP_OGT
0 0 1 0 True if ordered and greater than
 
@ FCMP_OGE
0 0 1 1 True if ordered and greater than or equal
 
@ ICMP_SGT
signed greater than
 
@ FCMP_ULT
1 1 0 0 True if unordered or less than
 
@ FCMP_ONE
0 1 1 0 True if ordered and operands are unequal
 
@ FCMP_UEQ
1 0 0 1 True if unordered or equal
 
@ FCMP_UGT
1 0 1 0 True if unordered or greater than
 
@ FCMP_OLE
0 1 0 1 True if ordered and less than or equal
 
@ FCMP_ORD
0 1 1 1 True if ordered (no nans)
 
@ ICMP_SGE
signed greater or equal
 
@ FCMP_UNE
1 1 1 0 True if unordered or not equal
 
@ FCMP_UGE
1 0 1 1 True if unordered, greater than, or equal
 
@ FCMP_FALSE
0 0 0 0 Always false (always folded)
 
@ FCMP_UNO
1 0 0 0 True if unordered: isnan(X) | isnan(Y)
 
bool isFPPredicate() const
 
static bool isIntPredicate(Predicate P)
 
This is the shared class of boolean and integer constants.
 
uint64_t getZExtValue() const
Return the constant as a 64-bit unsigned integer value after it has been zero extended as appropriate...
 
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
 
void resize(typename StorageT::size_type S)
 
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
 
static constexpr LLT pointer(unsigned AddressSpace, unsigned SizeInBits)
Get a low-level pointer in the given address space.
 
This is an important class for using LLVM in a threaded context.
 
LegalizeRuleSet & legalFor(std::initializer_list< LLT > Types)
The instruction is legal when type index 0 is any type in the given list.
 
LegalizeRuleSet & libcallFor(std::initializer_list< LLT > Types)
 
LegalizeRuleSet & maxScalar(unsigned TypeIdx, const LLT Ty)
Ensure the scalar is at most as wide as Ty.
 
LegalizeRuleSet & customForCartesianProduct(std::initializer_list< LLT > Types)
 
LegalizeRuleSet & lower()
The instruction is lowered.
 
LegalizeRuleSet & lowerFor(std::initializer_list< LLT > Types)
The instruction is lowered when type index 0 is any type in the given list.
 
LegalizeRuleSet & clampScalar(unsigned TypeIdx, const LLT MinTy, const LLT MaxTy)
Limit the range of scalar sizes to MinTy and MaxTy.
 
LegalizeRuleSet & custom()
Unconditionally custom lower.
 
LegalizeRuleSet & alwaysLegal()
 
LegalizeRuleSet & legalForCartesianProduct(std::initializer_list< LLT > Types)
The instruction is legal when type indexes 0 and 1 are both in the given list.
 
LegalizeRuleSet & legalForTypesWithMemDesc(std::initializer_list< LegalityPredicates::TypePairAndMemDesc > TypesAndMemDesc)
The instruction is legal when type indexes 0 and 1 along with the memory size and minimum alignment i...
 
LegalizeRuleSet & customFor(std::initializer_list< LLT > Types)
 
@ Legalized
Instruction has been legalized and the MachineFunction changed.
 
MachineIRBuilder & MIRBuilder
Expose MIRBuilder so clients can set their own RecordInsertInstruction functions.
 
LLVM_ABI LegalizeResult lowerConstant(MachineInstr &MI)
 
LegalizeRuleSet & getActionDefinitionsBuilder(unsigned Opcode)
Get the action definition builder for the given opcode.
 
const LegacyLegalizerInfo & getLegacyLegalizerInfo() const
 
Function & getFunction()
Return the LLVM function that this machine code represents.
 
Helper class to build MachineInstr.
 
MachineInstrBuilder buildAnd(const DstOp &Dst, const SrcOp &Src0, const SrcOp &Src1)
Build and insert Res = G_AND Op0, Op1.
 
MachineInstrBuilder buildICmp(CmpInst::Predicate Pred, const DstOp &Res, const SrcOp &Op0, const SrcOp &Op1, std::optional< unsigned > Flags=std::nullopt)
Build and insert a Res = G_ICMP Pred, Op0, Op1.
 
MachineFunction & getMF()
Getter for the function we currently build.
 
MachineInstrBuilder buildTrunc(const DstOp &Res, const SrcOp &Op, std::optional< unsigned > Flags=std::nullopt)
Build and insert Res = G_TRUNC Op.
 
MachineInstrBuilder buildGetFPEnv(const DstOp &Dst)
Build and insert Dst = G_GET_FPENV.
 
MachineRegisterInfo * getMRI()
Getter for MRI.
 
MachineInstrBuilder buildOr(const DstOp &Dst, const SrcOp &Src0, const SrcOp &Src1, std::optional< unsigned > Flags=std::nullopt)
Build and insert Res = G_OR Op0, Op1.
 
virtual MachineInstrBuilder buildConstant(const DstOp &Res, const ConstantInt &Val)
Build and insert Res = G_CONSTANT Val.
 
MachineInstrBuilder buildSetFPEnv(const SrcOp &Src)
Build and insert G_SET_FPENV Src.
 
Representation of each machine instruction.
 
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
 
Wrapper class representing virtual and physical registers.
 
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
 
Class to represent struct types.
 
static LLVM_ABI StructType * get(LLVMContext &Context, ArrayRef< Type * > Elements, bool isPacked=false)
This static method is the primary way to create a literal StructType.
 
The instances of the Type class are immutable: once they are created, they are never changed.
 
static LLVM_ABI IntegerType * getInt32Ty(LLVMContext &C)
 
static LLVM_ABI Type * getDoubleTy(LLVMContext &C)
 
static LLVM_ABI Type * getFloatTy(LLVMContext &C)
 
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
 
const unsigned FPStatusBits
 
const unsigned FPReservedBits
 
@ Libcall
The operation should be implemented as a call to some kind of runtime support library.
 
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
 
Invariant opcodes: All instruction sets have these as their low opcodes.
 
This is an optimization pass for GlobalISel generic memory operations.
 
LLVM_ABI LegalizerHelper::LegalizeResult createLibcall(MachineIRBuilder &MIRBuilder, const char *Name, const CallLowering::ArgInfo &Result, ArrayRef< CallLowering::ArgInfo > Args, CallingConv::ID CC, LostDebugLocObserver &LocObserver, MachineInstr *MI=nullptr)
Helper function that creates a libcall to the given Name using the given calling convention CC.
 
unsigned ConstantMaterializationCost(unsigned Val, const ARMSubtarget *Subtarget, bool ForCodesize=false)
Returns the number of instructions required to materialize the given constant in a register,...