1 //===- ARMLegalizerInfo.cpp --------------------------------------*- C++ -*-==// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 /// \file 10 /// This file implements the targeting of the Machinelegalizer class for ARM. 11 /// \todo This should be generated by TableGen. 12 //===----------------------------------------------------------------------===// 13 14 #include "ARMLegalizerInfo.h" 15 #include "ARMCallLowering.h" 16 #include "ARMSubtarget.h" 17 #include "llvm/CodeGen/GlobalISel/LegalizerHelper.h" 18 #include "llvm/CodeGen/LowLevelType.h" 19 #include "llvm/CodeGen/MachineRegisterInfo.h" 20 #include "llvm/CodeGen/ValueTypes.h" 21 #include "llvm/IR/DerivedTypes.h" 22 #include "llvm/IR/Type.h" 23 #include "llvm/Target/TargetOpcodes.h" 24 25 using namespace llvm; 26 27 #ifndef LLVM_BUILD_GLOBAL_ISEL 28 #error "You shouldn't build this" 29 #endif 30 31 static bool AEABI(const ARMSubtarget &ST) { 32 return ST.isTargetAEABI() || ST.isTargetGNUAEABI() || ST.isTargetMuslAEABI(); 33 } 34 35 ARMLegalizerInfo::ARMLegalizerInfo(const ARMSubtarget &ST) { 36 using namespace TargetOpcode; 37 38 const LLT p0 = LLT::pointer(0, 32); 39 40 const LLT s1 = LLT::scalar(1); 41 const LLT s8 = LLT::scalar(8); 42 const LLT s16 = LLT::scalar(16); 43 const LLT s32 = LLT::scalar(32); 44 const LLT s64 = LLT::scalar(64); 45 46 setAction({G_FRAME_INDEX, p0}, Legal); 47 48 for (unsigned Op : {G_LOAD, G_STORE}) { 49 for (auto Ty : {s1, s8, s16, s32, p0}) 50 setAction({Op, Ty}, Legal); 51 setAction({Op, 1, p0}, Legal); 52 } 53 54 for (unsigned Op : {G_ADD, G_SUB, G_MUL, G_AND, G_OR, G_XOR}) { 55 for (auto Ty : {s1, s8, s16}) 56 setAction({Op, Ty}, WidenScalar); 57 setAction({Op, s32}, Legal); 58 } 59 60 for (unsigned Op : {G_SDIV, G_UDIV}) { 61 for (auto Ty : {s8, s16}) 62 setAction({Op, Ty}, WidenScalar); 63 if (ST.hasDivideInARMMode()) 64 setAction({Op, s32}, Legal); 65 else 66 setAction({Op, s32}, Libcall); 67 } 68 69 // FIXME: Support s8 and s16 as well 70 for (unsigned Op : {G_SREM, G_UREM}) 71 if (ST.hasDivideInARMMode()) 72 setAction({Op, s32}, Lower); 73 else if (AEABI(ST)) 74 setAction({Op, s32}, Custom); 75 else 76 setAction({Op, s32}, Libcall); 77 78 for (unsigned Op : {G_SEXT, G_ZEXT}) { 79 setAction({Op, s32}, Legal); 80 for (auto Ty : {s1, s8, s16}) 81 setAction({Op, 1, Ty}, Legal); 82 } 83 84 setAction({G_GEP, p0}, Legal); 85 setAction({G_GEP, 1, s32}, Legal); 86 87 setAction({G_SELECT, s32}, Legal); 88 setAction({G_SELECT, p0}, Legal); 89 setAction({G_SELECT, 1, s1}, Legal); 90 91 setAction({G_CONSTANT, s32}, Legal); 92 93 setAction({G_ICMP, s1}, Legal); 94 for (auto Ty : {s8, s16}) 95 setAction({G_ICMP, 1, Ty}, WidenScalar); 96 for (auto Ty : {s32, p0}) 97 setAction({G_ICMP, 1, Ty}, Legal); 98 99 if (!ST.useSoftFloat() && ST.hasVFP2()) { 100 setAction({G_FADD, s32}, Legal); 101 setAction({G_FADD, s64}, Legal); 102 103 setAction({G_LOAD, s64}, Legal); 104 setAction({G_STORE, s64}, Legal); 105 } else { 106 for (auto Ty : {s32, s64}) 107 setAction({G_FADD, Ty}, Libcall); 108 } 109 110 for (unsigned Op : {G_FREM, G_FPOW}) 111 for (auto Ty : {s32, s64}) 112 setAction({Op, Ty}, Libcall); 113 114 computeTables(); 115 } 116 117 bool ARMLegalizerInfo::legalizeCustom(MachineInstr &MI, 118 MachineRegisterInfo &MRI, 119 MachineIRBuilder &MIRBuilder) const { 120 using namespace TargetOpcode; 121 122 switch (MI.getOpcode()) { 123 default: 124 return false; 125 case G_SREM: 126 case G_UREM: { 127 unsigned OriginalResult = MI.getOperand(0).getReg(); 128 auto Size = MRI.getType(OriginalResult).getSizeInBits(); 129 if (Size != 32) 130 return false; 131 132 auto Libcall = 133 MI.getOpcode() == G_SREM ? RTLIB::SDIVREM_I32 : RTLIB::UDIVREM_I32; 134 135 // Our divmod libcalls return a struct containing the quotient and the 136 // remainder. We need to create a virtual register for it. 137 auto &Ctx = MIRBuilder.getMF().getFunction()->getContext(); 138 Type *ArgTy = Type::getInt32Ty(Ctx); 139 StructType *RetTy = StructType::get(Ctx, {ArgTy, ArgTy}, /* Packed */ true); 140 auto RetVal = MRI.createGenericVirtualRegister( 141 getLLTForType(*RetTy, MIRBuilder.getMF().getDataLayout())); 142 143 auto Status = replaceWithLibcall(MI, MIRBuilder, Libcall, {RetVal, RetTy}, 144 {{MI.getOperand(1).getReg(), ArgTy}, 145 {MI.getOperand(2).getReg(), ArgTy}}); 146 if (Status != LegalizerHelper::Legalized) 147 return false; 148 149 // The remainder is the second result of divmod. Split the return value into 150 // a new, unused register for the quotient and the destination of the 151 // original instruction for the remainder. 152 MIRBuilder.buildUnmerge( 153 {MRI.createGenericVirtualRegister(LLT::scalar(32)), OriginalResult}, 154 RetVal); 155 156 return LegalizerHelper::Legalized; 157 } 158 } 159 } 160