26 using namespace LegalizeActions;
40 for (
unsigned i = 0;
i < v.size(); ++
i) {
42 if (
i + 1 < v[
i].first &&
i + 1 < v.size() &&
43 v[
i + 1].first != v[
i].first + 1)
59 auto Largest =
result.back().first;
65 return ST.isTargetAEABI() ||
ST.isTargetGNUAEABI() ||
ST.isTargetMuslAEABI();
69 using namespace TargetOpcode;
79 auto &LegacyInfo = getLegacyLegalizerInfo();
80 if (
ST.isThumb1Only()) {
82 LegacyInfo.computeTables();
87 getActionDefinitionsBuilder({G_SEXT, G_ZEXT, G_ANYEXT})
88 .legalForCartesianProduct({s8, s16, s32}, {
s1, s8, s16});
90 getActionDefinitionsBuilder(G_SEXT_INREG).lower();
92 getActionDefinitionsBuilder({G_MUL, G_AND, G_OR, G_XOR})
94 .clampScalar(0, s32, s32);
97 getActionDefinitionsBuilder({G_ADD, G_SUB})
101 getActionDefinitionsBuilder({G_ADD, G_SUB})
105 getActionDefinitionsBuilder({G_ASHR, G_LSHR, G_SHL})
106 .legalFor({{s32, s32}})
108 .clampScalar(1, s32, s32);
110 bool HasHWDivide = (!
ST.isThumb() &&
ST.hasDivideInARMMode()) ||
111 (
ST.isThumb() &&
ST.hasDivideInThumbMode());
113 getActionDefinitionsBuilder({G_SDIV, G_UDIV})
115 .clampScalar(0, s32, s32);
117 getActionDefinitionsBuilder({G_SDIV, G_UDIV})
119 .clampScalar(0, s32, s32);
121 for (
unsigned Op : {G_SREM, G_UREM}) {
122 LegacyInfo.setLegalizeScalarToDifferentSizeStrategy(
Op, 0,
widen_8_16);
131 getActionDefinitionsBuilder(G_INTTOPTR)
132 .legalFor({{p0, s32}})
134 getActionDefinitionsBuilder(G_PTRTOINT)
135 .legalFor({{s32, p0}})
138 getActionDefinitionsBuilder(G_CONSTANT)
140 .clampScalar(0, s32, s32);
142 getActionDefinitionsBuilder(G_ICMP)
143 .legalForCartesianProduct({
s1}, {s32, p0})
146 getActionDefinitionsBuilder(G_SELECT)
147 .legalForCartesianProduct({s32, p0}, {
s1})
152 auto &LoadStoreBuilder = getActionDefinitionsBuilder({G_LOAD, G_STORE})
153 .legalForTypesWithMemDesc({{s8, p0, s8, 8},
157 .unsupportedIfMemSizeNotPow2();
159 getActionDefinitionsBuilder(G_FRAME_INDEX).legalFor({p0});
160 getActionDefinitionsBuilder(G_GLOBAL_VALUE).legalFor({p0});
163 getActionDefinitionsBuilder(G_PHI)
167 getActionDefinitionsBuilder(G_PTR_ADD)
168 .legalFor({{p0, s32}})
171 getActionDefinitionsBuilder(G_BRCOND).legalFor({
s1});
173 if (!
ST.useSoftFloat() &&
ST.hasVFP2Base()) {
174 getActionDefinitionsBuilder(
175 {G_FADD, G_FSUB, G_FMUL, G_FDIV, G_FCONSTANT, G_FNEG})
176 .legalFor({s32, s64});
179 .legalForTypesWithMemDesc({{s64, p0, s64, 32}})
181 PhiBuilder.legalFor({s64});
183 getActionDefinitionsBuilder(G_FCMP).legalForCartesianProduct({
s1},
186 getActionDefinitionsBuilder(G_MERGE_VALUES).legalFor({{s64, s32}});
187 getActionDefinitionsBuilder(G_UNMERGE_VALUES).legalFor({{s32, s64}});
189 getActionDefinitionsBuilder(G_FPEXT).legalFor({{s64, s32}});
190 getActionDefinitionsBuilder(G_FPTRUNC).legalFor({{s32, s64}});
192 getActionDefinitionsBuilder({G_FPTOSI, G_FPTOUI})
193 .legalForCartesianProduct({s32}, {s32, s64});
194 getActionDefinitionsBuilder({G_SITOFP, G_UITOFP})
195 .legalForCartesianProduct({s32, s64}, {s32});
197 getActionDefinitionsBuilder({G_FADD, G_FSUB, G_FMUL, G_FDIV})
198 .libcallFor({s32, s64});
200 LoadStoreBuilder.maxScalar(0, s32);
202 for (
auto Ty : {s32, s64})
205 getActionDefinitionsBuilder(G_FCONSTANT).customFor({s32, s64});
207 getActionDefinitionsBuilder(G_FCMP).customForCartesianProduct({
s1},
211 setFCmpLibcallsAEABI();
213 setFCmpLibcallsGNU();
215 getActionDefinitionsBuilder(G_FPEXT).libcallFor({{s64, s32}});
216 getActionDefinitionsBuilder(G_FPTRUNC).libcallFor({{s32, s64}});
218 getActionDefinitionsBuilder({G_FPTOSI, G_FPTOUI})
219 .libcallForCartesianProduct({s32}, {s32, s64});
220 getActionDefinitionsBuilder({G_SITOFP, G_UITOFP})
221 .libcallForCartesianProduct({s32, s64}, {s32});
225 LoadStoreBuilder.lower();
227 if (!
ST.useSoftFloat() &&
ST.hasVFP4Base())
228 getActionDefinitionsBuilder(G_FMA).legalFor({s32, s64});
230 getActionDefinitionsBuilder(G_FMA).libcallFor({s32, s64});
232 getActionDefinitionsBuilder({G_FREM, G_FPOW}).libcallFor({s32, s64});
234 if (
ST.hasV5TOps()) {
235 getActionDefinitionsBuilder(G_CTLZ)
236 .legalFor({s32, s32})
237 .clampScalar(1, s32, s32)
238 .clampScalar(0, s32, s32);
239 getActionDefinitionsBuilder(G_CTLZ_ZERO_UNDEF)
240 .lowerFor({s32, s32})
241 .clampScalar(1, s32, s32)
242 .clampScalar(0, s32, s32);
244 getActionDefinitionsBuilder(G_CTLZ_ZERO_UNDEF)
245 .libcallFor({s32, s32})
246 .clampScalar(1, s32, s32)
247 .clampScalar(0, s32, s32);
248 getActionDefinitionsBuilder(G_CTLZ)
249 .lowerFor({s32, s32})
250 .clampScalar(1, s32, s32)
251 .clampScalar(0, s32, s32);
254 LegacyInfo.computeTables();
258 void ARMLegalizerInfo::setFCmpLibcallsAEABI() {
314 void ARMLegalizerInfo::setFCmpLibcallsGNU() {
356 unsigned Size)
const {
367 using namespace TargetOpcode;
373 switch (
MI.getOpcode()) {
378 Register OriginalResult =
MI.getOperand(0).getReg();
384 MI.getOpcode() == G_SREM ? RTLIB::SDIVREM_I32 : RTLIB::UDIVREM_I32;
394 {{
MI.getOperand(1).
getReg(), ArgTy, 0},
395 {
MI.getOperand(2).
getReg(), ArgTy, 0}});
403 "Mismatched operands for G_FCMP");
406 auto OriginalResult =
MI.getOperand(0).getReg();
409 auto Libcalls = getFCmpLibcalls(
Predicate, OpSize);
411 if (Libcalls.empty()) {
414 "Predicate needs libcalls, but none specified");
417 MI.eraseFromParent();
421 assert((OpSize == 32 || OpSize == 64) &&
"Unsupported operand size");
426 for (
auto Libcall : Libcalls) {
429 {LibcallResult, RetTy, 0},
430 {{MI.getOperand(2).getReg(), ArgTy, 0},
431 {MI.getOperand(3).getReg(), ArgTy, 0}});
436 auto ProcessedResult =
448 MIRBuilder.
buildTrunc(ProcessedResult, LibcallResult);
453 MIRBuilder.
buildICmp(ResultPred, ProcessedResult, LibcallResult, Zero);
455 Results.push_back(ProcessedResult);
467 MI.getOperand(1).getFPImm()->getValueAPF().bitcastToAPInt();
474 MI.eraseFromParent();