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 ARMLegalizerInfo::ARMLegalizerInfo(const ARMSubtarget &ST) { 32 using namespace TargetOpcode; 33 34 const LLT p0 = LLT::pointer(0, 32); 35 36 const LLT s1 = LLT::scalar(1); 37 const LLT s8 = LLT::scalar(8); 38 const LLT s16 = LLT::scalar(16); 39 const LLT s32 = LLT::scalar(32); 40 const LLT s64 = LLT::scalar(64); 41 42 setAction({G_FRAME_INDEX, p0}, Legal); 43 44 for (unsigned Op : {G_LOAD, G_STORE}) { 45 for (auto Ty : {s1, s8, s16, s32, p0}) 46 setAction({Op, Ty}, Legal); 47 setAction({Op, 1, p0}, Legal); 48 } 49 50 for (unsigned Op : {G_ADD, G_SUB, G_MUL, G_AND, G_OR, G_XOR}) { 51 for (auto Ty : {s1, s8, s16}) 52 setAction({Op, Ty}, WidenScalar); 53 setAction({Op, s32}, Legal); 54 } 55 56 for (unsigned Op : {G_SDIV, G_UDIV}) { 57 for (auto Ty : {s8, s16}) 58 // FIXME: We need WidenScalar here, but in the case of targets with 59 // software division we'll also need Libcall afterwards. Treat as Custom 60 // until we have better support for chaining legalization actions. 61 setAction({Op, Ty}, Custom); 62 if (ST.hasDivideInARMMode()) 63 setAction({Op, s32}, Legal); 64 else 65 setAction({Op, s32}, Libcall); 66 } 67 68 // FIXME: Support s8 and s16 as well 69 for (unsigned Op : {G_SREM, G_UREM}) 70 if (ST.hasDivideInARMMode()) 71 setAction({Op, s32}, Lower); 72 else if (ST.isTargetAEABI() || ST.isTargetGNUAEABI() || 73 ST.isTargetMuslAEABI()) 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_CONSTANT, s32}, Legal); 88 89 setAction({G_ICMP, s1}, Legal); 90 for (auto Ty : {s8, s16}) 91 setAction({G_ICMP, 1, Ty}, WidenScalar); 92 for (auto Ty : {s32, p0}) 93 setAction({G_ICMP, 1, Ty}, Legal); 94 95 if (!ST.useSoftFloat() && ST.hasVFP2()) { 96 setAction({G_FADD, s32}, Legal); 97 setAction({G_FADD, s64}, Legal); 98 99 setAction({G_LOAD, s64}, Legal); 100 setAction({G_STORE, s64}, Legal); 101 } else { 102 for (auto Ty : {s32, s64}) 103 setAction({G_FADD, Ty}, Libcall); 104 } 105 106 for (unsigned Op : {G_FREM, G_FPOW}) 107 for (auto Ty : {s32, s64}) 108 setAction({Op, Ty}, Libcall); 109 110 computeTables(); 111 } 112 113 bool ARMLegalizerInfo::legalizeCustom(MachineInstr &MI, 114 MachineRegisterInfo &MRI, 115 MachineIRBuilder &MIRBuilder) const { 116 using namespace TargetOpcode; 117 118 switch (MI.getOpcode()) { 119 default: 120 return false; 121 case G_SDIV: 122 case G_UDIV: { 123 LLT Ty = MRI.getType(MI.getOperand(0).getReg()); 124 if (Ty != LLT::scalar(16) && Ty != LLT::scalar(8)) 125 return false; 126 127 // We need to widen to 32 bits and then maybe, if the target requires, 128 // transform into a libcall. 129 LegalizerHelper Helper(MIRBuilder.getMF()); 130 131 MachineInstr *NewMI = nullptr; 132 Helper.MIRBuilder.recordInsertions([&](MachineInstr *MI) { 133 // Store the new, 32-bit div instruction. 134 if (MI->getOpcode() == G_SDIV || MI->getOpcode() == G_UDIV) 135 NewMI = MI; 136 }); 137 138 auto Result = Helper.widenScalar(MI, 0, LLT::scalar(32)); 139 Helper.MIRBuilder.stopRecordingInsertions(); 140 if (Result == LegalizerHelper::UnableToLegalize) { 141 return false; 142 } 143 assert(NewMI && "Couldn't find widened instruction"); 144 assert((NewMI->getOpcode() == G_SDIV || NewMI->getOpcode() == G_UDIV) && 145 "Unexpected widened instruction"); 146 assert(MRI.getType(NewMI->getOperand(0).getReg()).getSizeInBits() == 32 && 147 "Unexpected type for the widened instruction"); 148 149 Result = Helper.legalizeInstrStep(*NewMI); 150 if (Result == LegalizerHelper::UnableToLegalize) { 151 return false; 152 } 153 return true; 154 } 155 case G_SREM: 156 case G_UREM: { 157 unsigned OriginalResult = MI.getOperand(0).getReg(); 158 auto Size = MRI.getType(OriginalResult).getSizeInBits(); 159 if (Size != 32) 160 return false; 161 162 auto Libcall = 163 MI.getOpcode() == G_SREM ? RTLIB::SDIVREM_I32 : RTLIB::UDIVREM_I32; 164 165 // Our divmod libcalls return a struct containing the quotient and the 166 // remainder. We need to create a virtual register for it. 167 auto &Ctx = MIRBuilder.getMF().getFunction()->getContext(); 168 Type *ArgTy = Type::getInt32Ty(Ctx); 169 StructType *RetTy = StructType::get(Ctx, {ArgTy, ArgTy}, /* Packed */ true); 170 auto RetVal = MRI.createGenericVirtualRegister( 171 getLLTForType(*RetTy, MIRBuilder.getMF().getDataLayout())); 172 173 auto Status = replaceWithLibcall(MI, MIRBuilder, Libcall, {RetVal, RetTy}, 174 {{MI.getOperand(1).getReg(), ArgTy}, 175 {MI.getOperand(2).getReg(), ArgTy}}); 176 if (Status != LegalizerHelper::Legalized) 177 return false; 178 179 // The remainder is the second result of divmod. Split the return value into 180 // a new, unused register for the quotient and the destination of the 181 // original instruction for the remainder. 182 MIRBuilder.buildUnmerge( 183 {MRI.createGenericVirtualRegister(LLT::scalar(32)), OriginalResult}, 184 RetVal); 185 186 return LegalizerHelper::Legalized; 187 } 188 } 189 } 190