ARMLegalizerInfo::ARMLegalizerInfo(const ARMSubtarget &ST) { using namespace TargetOpcode; const LLT p0 = LLT::pointer(0, 32); const LLT s1 = LLT::scalar(1); const LLT s8 = LLT::scalar(8); const LLT s16 = LLT::scalar(16); const LLT s32 = LLT::scalar(32); const LLT s64 = LLT::scalar(64); setAction({G_FRAME_INDEX, p0}, Legal); for (unsigned Op : {G_LOAD, G_STORE}) { for (auto Ty : {s1, s8, s16, s32, p0}) setAction({Op, Ty}, Legal); setAction({Op, 1, p0}, Legal); } for (unsigned Op : {G_ADD, G_SUB, G_MUL}) for (auto Ty : {s1, s8, s16, s32}) setAction({Op, Ty}, Legal); for (unsigned Op : {G_SDIV, G_UDIV}) { for (auto Ty : {s8, s16}) // FIXME: We need WidenScalar here, but in the case of targets with // software division we'll also need Libcall afterwards. Treat as Custom // until we have better support for chaining legalization actions. setAction({Op, Ty}, Custom); if (ST.hasDivideInARMMode()) setAction({Op, s32}, Legal); else setAction({Op, s32}, Libcall); } for (unsigned Op : {G_SEXT, G_ZEXT}) { setAction({Op, s32}, Legal); for (auto Ty : {s1, s8, s16}) setAction({Op, 1, Ty}, Legal); } setAction({G_GEP, p0}, Legal); setAction({G_GEP, 1, s32}, Legal); setAction({G_CONSTANT, s32}, Legal); if (!ST.useSoftFloat() && ST.hasVFP2()) { setAction({G_FADD, s32}, Legal); setAction({G_FADD, s64}, Legal); setAction({G_LOAD, s64}, Legal); setAction({G_STORE, s64}, Legal); } else { for (auto Ty : {s32, s64}) setAction({G_FADD, Ty}, Libcall); } for (unsigned Op : {G_FREM, G_FPOW}) for (auto Ty : {s32, s64}) setAction({Op, Ty}, Libcall); computeTables(); }
ARMLegalizerInfo::ARMLegalizerInfo(const ARMSubtarget &ST) { using namespace TargetOpcode; const LLT p0 = LLT::pointer(0, 32); const LLT s1 = LLT::scalar(1); const LLT s8 = LLT::scalar(8); const LLT s16 = LLT::scalar(16); const LLT s32 = LLT::scalar(32); const LLT s64 = LLT::scalar(64); setAction({G_GLOBAL_VALUE, p0}, Legal); setAction({G_FRAME_INDEX, p0}, Legal); for (unsigned Op : {G_LOAD, G_STORE}) { for (auto Ty : {s1, s8, s16, s32, p0}) setAction({Op, Ty}, Legal); setAction({Op, 1, p0}, Legal); } for (unsigned Op : {G_ADD, G_SUB, G_MUL, G_AND, G_OR, G_XOR}) { for (auto Ty : {s1, s8, s16}) setAction({Op, Ty}, WidenScalar); setAction({Op, s32}, Legal); } for (unsigned Op : {G_SDIV, G_UDIV}) { for (auto Ty : {s8, s16}) setAction({Op, Ty}, WidenScalar); if (ST.hasDivideInARMMode()) setAction({Op, s32}, Legal); else setAction({Op, s32}, Libcall); } for (unsigned Op : {G_SREM, G_UREM}) { for (auto Ty : {s8, s16}) setAction({Op, Ty}, WidenScalar); if (ST.hasDivideInARMMode()) setAction({Op, s32}, Lower); else if (AEABI(ST)) setAction({Op, s32}, Custom); else setAction({Op, s32}, Libcall); } for (unsigned Op : {G_SEXT, G_ZEXT}) { setAction({Op, s32}, Legal); for (auto Ty : {s1, s8, s16}) setAction({Op, 1, Ty}, Legal); } for (unsigned Op : {G_ASHR, G_LSHR, G_SHL}) setAction({Op, s32}, Legal); setAction({G_GEP, p0}, Legal); setAction({G_GEP, 1, s32}, Legal); setAction({G_SELECT, s32}, Legal); setAction({G_SELECT, p0}, Legal); setAction({G_SELECT, 1, s1}, Legal); setAction({G_BRCOND, s1}, Legal); setAction({G_CONSTANT, s32}, Legal); for (auto Ty : {s1, s8, s16}) setAction({G_CONSTANT, Ty}, WidenScalar); setAction({G_ICMP, s1}, Legal); for (auto Ty : {s8, s16}) setAction({G_ICMP, 1, Ty}, WidenScalar); for (auto Ty : {s32, p0}) setAction({G_ICMP, 1, Ty}, Legal); if (!ST.useSoftFloat() && ST.hasVFP2()) { setAction({G_FADD, s32}, Legal); setAction({G_FADD, s64}, Legal); setAction({G_LOAD, s64}, Legal); setAction({G_STORE, s64}, Legal); setAction({G_FCMP, s1}, Legal); setAction({G_FCMP, 1, s32}, Legal); setAction({G_FCMP, 1, s64}, Legal); } else { for (auto Ty : {s32, s64}) setAction({G_FADD, Ty}, Libcall); setAction({G_FCMP, s1}, Legal); setAction({G_FCMP, 1, s32}, Custom); setAction({G_FCMP, 1, s64}, Custom); if (AEABI(ST)) setFCmpLibcallsAEABI(); else setFCmpLibcallsGNU(); } for (unsigned Op : {G_FREM, G_FPOW}) for (auto Ty : {s32, s64}) setAction({Op, Ty}, Libcall); computeTables(); }