15
15
#include " Z80MachineFunctionInfo.h"
16
16
#include " Z80Subtarget.h"
17
17
#include " Z80TargetMachine.h"
18
+ #include " llvm/ADT/STLExtras.h"
18
19
#include " llvm/CodeGen/GlobalISel/LegalizerHelper.h"
19
20
#include " llvm/CodeGen/GlobalISel/MIPatternMatch.h"
20
21
#include " llvm/CodeGen/GlobalISel/MachineIRBuilder.h"
@@ -26,10 +27,49 @@ using namespace TargetOpcode;
26
27
using namespace LegalizeActions ;
27
28
using namespace MIPatternMatch ;
28
29
30
+ static LegalityPredicate typeNotInSet (unsigned TypeIdx,
31
+ std::initializer_list<LLT> TypesInit) {
32
+ using namespace LegalityPredicates ;
33
+ SmallVector<LLT, 8 > Types = TypesInit;
34
+ return [=](const LegalityQuery &Query) {
35
+ return !is_contained (Types, Query.Types [TypeIdx]);
36
+ };
37
+ }
38
+
39
+ static LegalityPredicate scalarNotInSet (unsigned TypeIdx,
40
+ std::initializer_list<LLT> Types) {
41
+ using namespace LegalityPredicates ;
42
+ return all (isScalar (TypeIdx), typeNotInSet (TypeIdx, Types));
43
+ }
44
+
45
+ static LegalizeRuleSet &
46
+ widenScalarToNextOrNarrowToLast (LegalizeRuleSet &Builder, unsigned TypeIdx,
47
+ std::initializer_list<LLT> TypesInit) {
48
+ using namespace LegalityPredicates ;
49
+ SmallVector<LLT, 8 > Types = TypesInit;
50
+ assert (!Types.empty () && is_sorted (Types, [](LLT Ty1, LLT Ty2) {
51
+ return Ty1.getSizeInBits () < Ty2.getSizeInBits ();
52
+ }) && " Expected type set to be not empty and sorted by width." );
53
+ return Builder.maxScalar (TypeIdx, Types.back ())
54
+ .widenScalarIf (
55
+ scalarNotInSet (TypeIdx, TypesInit), [=](const LegalityQuery &Query) {
56
+ LLT QueryTy = Query.Types [TypeIdx];
57
+ for (LLT Ty : reverse (Types))
58
+ if (QueryTy.getSizeInBits () < Ty.getSizeInBits ())
59
+ return std::make_pair (TypeIdx, Ty);
60
+ llvm_unreachable (" Scalar wider than last already handled." );
61
+ });
62
+ }
63
+
29
64
Z80LegalizerInfo::Z80LegalizerInfo (const Z80Subtarget &STI,
30
65
const Z80TargetMachine &TM)
31
66
: Subtarget(STI), TM(TM) {
67
+ using namespace LegalizeActions ;
68
+ using namespace LegalityPredicates ;
69
+ using namespace LegalizeMutations ;
70
+
32
71
bool Is24Bit = Subtarget.is24Bit ();
72
+ LegalityPredicate pred24Bit = [=](const LegalityQuery &) { return Is24Bit; };
33
73
34
74
std::array<LLT, 5 > p;
35
75
for (int AddrSpace = 0 ; AddrSpace != p.size (); ++AddrSpace)
@@ -39,6 +79,7 @@ Z80LegalizerInfo::Z80LegalizerInfo(const Z80Subtarget &STI,
39
79
LLT s16 = LLT::scalar (16 );
40
80
LLT s24 = LLT::scalar (24 );
41
81
LLT s32 = LLT::scalar (32 );
82
+ LLT s48 = LLT::scalar (48 );
42
83
LLT s64 = LLT::scalar (64 );
43
84
LLT sMax = Is24Bit ? s24 : s16;
44
85
LLT sOther = Is24Bit ? s16 : s24;
@@ -57,6 +98,9 @@ Z80LegalizerInfo::Z80LegalizerInfo(const Z80Subtarget &STI,
57
98
auto LegalLibcallScalars16 = {s8, s16, s32, s64};
58
99
auto LegalLibcallScalars =
59
100
Is24Bit ? LegalLibcallScalars24 : LegalLibcallScalars16;
101
+ auto LibcallScalars24 = {s8, s16, s24, s32, s48, s64};
102
+ auto LibcallScalars16 = {s8, s16, s32, s64};
103
+ auto LibcallScalars = Is24Bit ? LibcallScalars24 : LibcallScalars16;
60
104
auto NotMax24 = {s8, s16}, NotMax16 = {s8};
61
105
auto NotMax = Is24Bit ? NotMax24 : NotMax16;
62
106
auto NotMin24 = {s16, s24}, NotMin16 = {s16};
@@ -159,13 +203,11 @@ Z80LegalizerInfo::Z80LegalizerInfo(const Z80Subtarget &STI,
159
203
.legalForCartesianProduct (LegalScalars, {s1})
160
204
.clampScalar (0 , s8, sMax );
161
205
162
- {
163
- auto &&Mul = getActionDefinitionsBuilder (G_MUL);
164
- if (Subtarget.hasZ180Ops ())
165
- Mul.legalFor ({s8});
166
- Mul.libcallFor (LegalLibcallScalars)
167
- .clampScalar (0 , s8, s32);
168
- }
206
+ getActionDefinitionsBuilder (G_MUL)
207
+ .legalIf (all (pred24Bit, typeIs (0 , s8)))
208
+ .libcallFor (LegalLibcallScalars)
209
+ .narrowScalarIf (all (pred24Bit, typeIs (0 , s48)), changeTo (0 , s24))
210
+ .clampScalar (0 , s8, s32);
169
211
170
212
getActionDefinitionsBuilder ({G_SDIV, G_UDIV, G_SREM, G_UREM})
171
213
.libcallFor (LegalLibcallScalars)
@@ -176,10 +218,12 @@ Z80LegalizerInfo::Z80LegalizerInfo(const Z80Subtarget &STI,
176
218
.customFor (LegalLibcallScalars)
177
219
.clampScalar (0 , s8, s32);
178
220
179
- getActionDefinitionsBuilder ({G_SHL, G_LSHR, G_ASHR})
180
- .customForCartesianProduct (LegalLibcallScalars, {s8})
181
- .clampScalar (1 , s8, s8)
182
- .clampScalar (0 , s8, s64);
221
+ widenScalarToNextOrNarrowToLast (
222
+ getActionDefinitionsBuilder ({G_SHL, G_LSHR, G_ASHR})
223
+ .customForCartesianProduct (LegalLibcallScalars, {s8})
224
+ .clampScalar (1 , s8, s8)
225
+ .narrowScalarIf (all (pred24Bit, typeIs (0 , s48)), changeTo (0 , s24)),
226
+ 0 , LibcallScalars);
183
227
184
228
getActionDefinitionsBuilder ({G_FSHL, G_FSHR, G_ROTR, G_ROTL, G_UMULO,
185
229
G_UMULFIX, G_SMULFIX, G_SMULFIXSAT, G_UMULFIXSAT,
@@ -260,11 +304,10 @@ Z80LegalizerInfo::Z80LegalizerInfo(const Z80Subtarget &STI,
260
304
.customForCartesianProduct ({s1}, {s32, s64})
261
305
.clampScalar (1 , s8, s64);
262
306
263
- getActionDefinitionsBuilder (G_FCMP)
264
- . customForCartesianProduct ({s1}, {s32, s64});
307
+ getActionDefinitionsBuilder (G_FCMP). customForCartesianProduct ({s1},
308
+ {s32, s64});
265
309
266
- getActionDefinitionsBuilder (G_BRCOND)
267
- .legalFor ({s1});
310
+ getActionDefinitionsBuilder (G_BRCOND).legalFor ({s1});
268
311
269
312
getActionDefinitionsBuilder (G_BRJT)
270
313
.legalForCartesianProduct ({p[0 ]}, LegalScalars)
0 commit comments