@@ -47,20 +47,14 @@ LoongArchTargetLowering::LoongArchTargetLowering(const TargetMachine &TM,
47
47
: TargetLowering(TM), Subtarget(STI) {
48
48
49
49
MVT GRLenVT = Subtarget.getGRLenVT ();
50
+
50
51
// Set up the register classes.
52
+
51
53
addRegisterClass (GRLenVT, &LoongArch::GPRRegClass);
52
54
if (Subtarget.hasBasicF ())
53
55
addRegisterClass (MVT::f32 , &LoongArch::FPR32RegClass);
54
56
if (Subtarget.hasBasicD ())
55
57
addRegisterClass (MVT::f64 , &LoongArch::FPR64RegClass);
56
- if (Subtarget.hasExtLSX ())
57
- for (auto VT : {MVT::v4f32, MVT::v2f64, MVT::v16i8, MVT::v8i16, MVT::v4i32,
58
- MVT::v2i64})
59
- addRegisterClass (VT, &LoongArch::LSX128RegClass);
60
- if (Subtarget.hasExtLASX ())
61
- for (auto VT : {MVT::v8f32, MVT::v4f64, MVT::v32i8, MVT::v16i16, MVT::v8i32,
62
- MVT::v4i64})
63
- addRegisterClass (VT, &LoongArch::LASX256RegClass);
64
58
65
59
static const MVT::SimpleValueType LSXVTs[] = {
66
60
MVT::v16i8, MVT::v8i16, MVT::v4i32, MVT::v2i64, MVT::v4f32, MVT::v2f64};
@@ -75,38 +69,57 @@ LoongArchTargetLowering::LoongArchTargetLowering(const TargetMachine &TM,
75
69
for (MVT VT : LASXVTs)
76
70
addRegisterClass (VT, &LoongArch::LASX256RegClass);
77
71
72
+ // Set operations for LA32 and LA64.
73
+
78
74
setLoadExtAction ({ISD::EXTLOAD, ISD::SEXTLOAD, ISD::ZEXTLOAD}, GRLenVT,
79
75
MVT::i1, Promote);
80
76
81
- // TODO: add necessary setOperationAction calls later.
82
77
setOperationAction (ISD::SHL_PARTS, GRLenVT, Custom);
83
78
setOperationAction (ISD::SRA_PARTS, GRLenVT, Custom);
84
79
setOperationAction (ISD::SRL_PARTS, GRLenVT, Custom);
85
80
setOperationAction (ISD::FP_TO_SINT, GRLenVT, Custom);
86
81
setOperationAction (ISD::ROTL, GRLenVT, Expand);
87
82
setOperationAction (ISD::CTPOP, GRLenVT, Expand);
88
- setOperationAction (ISD::DEBUGTRAP, MVT::Other, Legal);
89
- setOperationAction (ISD::TRAP, MVT::Other, Legal);
90
- setOperationAction (ISD::INTRINSIC_VOID, MVT::Other, Custom);
91
- setOperationAction (ISD::INTRINSIC_W_CHAIN, MVT::Other, Custom);
92
83
93
84
setOperationAction ({ISD::GlobalAddress, ISD::BlockAddress, ISD::ConstantPool,
94
- ISD::JumpTable},
85
+ ISD::JumpTable, ISD::GlobalTLSAddress },
95
86
GRLenVT, Custom);
96
87
97
- setOperationAction (ISD::GlobalTLSAddress, GRLenVT, Custom);
98
-
99
- setOperationAction (ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom);
100
-
101
- setOperationAction (ISD::EH_DWARF_CFA, MVT::i32 , Custom);
102
- if (Subtarget.is64Bit ())
103
- setOperationAction (ISD::EH_DWARF_CFA, MVT::i64 , Custom);
88
+ setOperationAction (ISD::EH_DWARF_CFA, GRLenVT, Custom);
104
89
105
90
setOperationAction (ISD::DYNAMIC_STACKALLOC, GRLenVT, Expand);
106
91
setOperationAction ({ISD::STACKSAVE, ISD::STACKRESTORE}, MVT::Other, Expand);
107
92
setOperationAction (ISD::VASTART, MVT::Other, Custom);
108
93
setOperationAction ({ISD::VAARG, ISD::VACOPY, ISD::VAEND}, MVT::Other, Expand);
109
94
95
+ setOperationAction (ISD::DEBUGTRAP, MVT::Other, Legal);
96
+ setOperationAction (ISD::TRAP, MVT::Other, Legal);
97
+
98
+ setOperationAction (ISD::INTRINSIC_VOID, MVT::Other, Custom);
99
+ setOperationAction (ISD::INTRINSIC_W_CHAIN, MVT::Other, Custom);
100
+ setOperationAction (ISD::INTRINSIC_WO_CHAIN, MVT::Other, Custom);
101
+
102
+ // Expand bitreverse.i16 with native-width bitrev and shift for now, before
103
+ // we get to know which of sll and revb.2h is faster.
104
+ setOperationAction (ISD::BITREVERSE, MVT::i8 , Custom);
105
+ setOperationAction (ISD::BITREVERSE, GRLenVT, Legal);
106
+
107
+ // LA32 does not have REVB.2W and REVB.D due to the 64-bit operands, and
108
+ // the narrower REVB.W does not exist. But LA32 does have REVB.2H, so i16
109
+ // and i32 could still be byte-swapped relatively cheaply.
110
+ setOperationAction (ISD::BSWAP, MVT::i16 , Custom);
111
+
112
+ setOperationAction (ISD::BR_JT, MVT::Other, Expand);
113
+ setOperationAction (ISD::BR_CC, GRLenVT, Expand);
114
+ setOperationAction (ISD::SELECT_CC, GRLenVT, Expand);
115
+ setOperationAction (ISD::SIGN_EXTEND_INREG, MVT::i1, Expand);
116
+ setOperationAction ({ISD::SMUL_LOHI, ISD::UMUL_LOHI}, GRLenVT, Expand);
117
+
118
+ setOperationAction (ISD::FP_TO_UINT, GRLenVT, Custom);
119
+ setOperationAction (ISD::UINT_TO_FP, GRLenVT, Expand);
120
+
121
+ // Set operations for LA64 only.
122
+
110
123
if (Subtarget.is64Bit ()) {
111
124
setOperationAction (ISD::SHL, MVT::i32 , Custom);
112
125
setOperationAction (ISD::SRA, MVT::i32 , Custom);
@@ -117,50 +130,39 @@ LoongArchTargetLowering::LoongArchTargetLowering(const TargetMachine &TM,
117
130
setOperationAction (ISD::ROTL, MVT::i32 , Custom);
118
131
setOperationAction (ISD::CTTZ, MVT::i32 , Custom);
119
132
setOperationAction (ISD::CTLZ, MVT::i32 , Custom);
120
- setOperationAction (ISD::INTRINSIC_VOID, MVT::i32 , Custom);
121
- setOperationAction (ISD::INTRINSIC_W_CHAIN, MVT::i32 , Custom);
122
- setOperationAction (ISD::INTRINSIC_W_CHAIN, MVT::Other, Custom);
133
+ setOperationAction (ISD::EH_DWARF_CFA, MVT::i32 , Custom);
123
134
setOperationAction (ISD::READ_REGISTER, MVT::i32 , Custom);
124
135
setOperationAction (ISD::WRITE_REGISTER, MVT::i32 , Custom);
136
+ setOperationAction (ISD::INTRINSIC_VOID, MVT::i32 , Custom);
125
137
setOperationAction (ISD::INTRINSIC_WO_CHAIN, MVT::i32 , Custom);
126
- if (Subtarget.hasBasicF () && !Subtarget.hasBasicD ())
127
- setOperationAction (ISD::FP_TO_UINT, MVT::i32 , Custom);
128
- if (Subtarget.hasBasicF ())
129
- setOperationAction (ISD::FRINT, MVT::f32 , Legal);
130
- if (Subtarget.hasBasicD ())
131
- setOperationAction (ISD::FRINT, MVT::f64 , Legal);
132
- }
138
+ setOperationAction (ISD::INTRINSIC_W_CHAIN, MVT::i32 , Custom);
133
139
134
- // LA32 does not have REVB.2W and REVB.D due to the 64-bit operands, and
135
- // the narrower REVB.W does not exist. But LA32 does have REVB.2H, so i16
136
- // and i32 could still be byte-swapped relatively cheaply.
137
- setOperationAction (ISD::BSWAP, MVT::i16 , Custom);
138
- if (Subtarget.is64Bit ()) {
140
+ setOperationAction (ISD::BITREVERSE, MVT::i32 , Custom);
139
141
setOperationAction (ISD::BSWAP, MVT::i32 , Custom);
140
142
}
141
143
142
- // Expand bitreverse.i16 with native-width bitrev and shift for now, before
143
- // we get to know which of sll and revb.2h is faster.
144
- setOperationAction (ISD::BITREVERSE, MVT::i8 , Custom);
145
- if (Subtarget.is64Bit ()) {
146
- setOperationAction (ISD::BITREVERSE, MVT::i32 , Custom);
147
- setOperationAction (ISD::BITREVERSE, MVT::i64 , Legal);
148
- } else {
149
- setOperationAction (ISD::BITREVERSE, MVT::i32 , Legal);
150
- setOperationAction (ISD::INTRINSIC_W_CHAIN, MVT::i64 , Custom);
144
+ // Set operations for LA32 only.
145
+
146
+ if (!Subtarget.is64Bit ) {
151
147
setOperationAction (ISD::READ_REGISTER, MVT::i64 , Custom);
152
148
setOperationAction (ISD::WRITE_REGISTER, MVT::i64 , Custom);
153
- setOperationAction (ISD::INTRINSIC_W_CHAIN, MVT::Other, Custom);
154
149
setOperationAction (ISD::INTRINSIC_VOID, MVT::i64 , Custom);
155
150
setOperationAction (ISD::INTRINSIC_WO_CHAIN, MVT::i64 , Custom);
151
+ setOperationAction (ISD::INTRINSIC_W_CHAIN, MVT::i64 , Custom);
152
+
153
+ // Set libcalls.
154
+ setLibcallName (RTLIB::MUL_I128, nullptr );
156
155
}
157
156
158
157
static const ISD::CondCode FPCCToExpand[] = {
159
158
ISD::SETOGT, ISD::SETOGE, ISD::SETUGT, ISD::SETUGE,
160
159
ISD::SETGE, ISD::SETNE, ISD::SETGT};
161
160
161
+ // Set operations for 'F' feature.
162
+
162
163
if (Subtarget.hasBasicF ()) {
163
164
setCondCodeAction (FPCCToExpand, MVT::f32 , Expand);
165
+
164
166
setOperationAction (ISD::SELECT_CC, MVT::f32 , Expand);
165
167
setOperationAction (ISD::BR_CC, MVT::f32 , Expand);
166
168
setOperationAction (ISD::FMA, MVT::f32 , Legal);
@@ -173,14 +175,30 @@ LoongArchTargetLowering::LoongArchTargetLowering(const TargetMachine &TM,
173
175
setOperationAction (ISD::FSINCOS, MVT::f32 , Expand);
174
176
setOperationAction (ISD::FPOW, MVT::f32 , Expand);
175
177
setOperationAction (ISD::FREM, MVT::f32 , Expand);
178
+
179
+ if (Subtarget.is64Bit ())
180
+ setOperationAction (ISD::FRINT, MVT::f32 , Legal);
181
+
182
+ if (!Subtarget.hasBasicD ()) {
183
+ setOperationAction (ISD::FP_TO_UINT, MVT::i32 , Custom);
184
+ if (Subtarget.is64Bit ()) {
185
+ setOperationAction (ISD::SINT_TO_FP, MVT::i64 , Custom);
186
+ setOperationAction (ISD::UINT_TO_FP, MVT::i64 , Custom);
187
+ }
188
+ }
176
189
}
190
+
191
+ // Set operations for 'D' feature.
192
+
177
193
if (Subtarget.hasBasicD ()) {
194
+ setLoadExtAction (ISD::EXTLOAD, MVT::f64 , MVT::f32 , Expand);
195
+ setTruncStoreAction (MVT::f64 , MVT::f32 , Expand);
178
196
setCondCodeAction (FPCCToExpand, MVT::f64 , Expand);
197
+
179
198
setOperationAction (ISD::SELECT_CC, MVT::f64 , Expand);
180
199
setOperationAction (ISD::BR_CC, MVT::f64 , Expand);
181
200
setOperationAction (ISD::STRICT_FSETCCS, MVT::f64 , Legal);
182
201
setOperationAction (ISD::STRICT_FSETCC, MVT::f64 , Legal);
183
- setLoadExtAction (ISD::EXTLOAD, MVT::f64 , MVT::f32 , Expand);
184
202
setOperationAction (ISD::FMA, MVT::f64 , Legal);
185
203
setOperationAction (ISD::FMINNUM_IEEE, MVT::f64 , Legal);
186
204
setOperationAction (ISD::FMAXNUM_IEEE, MVT::f64 , Legal);
@@ -189,35 +207,35 @@ LoongArchTargetLowering::LoongArchTargetLowering(const TargetMachine &TM,
189
207
setOperationAction (ISD::FSINCOS, MVT::f64 , Expand);
190
208
setOperationAction (ISD::FPOW, MVT::f64 , Expand);
191
209
setOperationAction (ISD::FREM, MVT::f64 , Expand);
192
- setTruncStoreAction (MVT::f64 , MVT::f32 , Expand);
193
- }
194
-
195
- setOperationAction (ISD::BR_JT, MVT::Other, Expand);
196
210
197
- setOperationAction (ISD::BR_CC, GRLenVT, Expand);
198
- setOperationAction (ISD::SELECT_CC, GRLenVT, Expand);
199
- setOperationAction (ISD::SIGN_EXTEND_INREG, MVT::i1, Expand);
200
- setOperationAction ({ISD::SMUL_LOHI, ISD::UMUL_LOHI}, GRLenVT, Expand);
201
- if (!Subtarget.is64Bit ())
202
- setLibcallName (RTLIB::MUL_I128, nullptr );
203
-
204
- setOperationAction (ISD::FP_TO_UINT, GRLenVT, Custom);
205
- setOperationAction (ISD::UINT_TO_FP, GRLenVT, Expand);
206
- if ((Subtarget.is64Bit () && Subtarget.hasBasicF () &&
207
- !Subtarget.hasBasicD ())) {
208
- setOperationAction (ISD::SINT_TO_FP, GRLenVT, Custom);
209
- setOperationAction (ISD::UINT_TO_FP, GRLenVT, Custom);
211
+ if (Subtarget.is64Bit ())
212
+ setOperationAction (ISD::FRINT, MVT::f64 , Legal);
210
213
}
211
214
215
+ // Set operations for 'LSX' feature.
216
+
212
217
if (Subtarget.hasExtLSX ())
213
218
setOperationAction ({ISD::UMAX, ISD::UMIN, ISD::SMAX, ISD::SMIN},
214
219
{MVT::v2i64, MVT::v4i32, MVT::v8i16, MVT::v16i8}, Legal);
215
220
221
+ // Set operations for 'LASX' feature.
222
+
216
223
if (Subtarget.hasExtLASX ())
217
224
setOperationAction ({ISD::UMAX, ISD::UMIN, ISD::SMAX, ISD::SMIN},
218
225
{MVT::v4i64, MVT::v8i32, MVT::v16i16, MVT::v32i8},
219
226
Legal);
220
227
228
+ // Set DAG combine for LA32 and LA64.
229
+
230
+ setTargetDAGCombine (ISD::AND);
231
+ setTargetDAGCombine (ISD::OR);
232
+ setTargetDAGCombine (ISD::SRL);
233
+
234
+ // Set DAG combine for 'LSX' feature.
235
+
236
+ if (Subtarget.hasExtLSX ())
237
+ setTargetDAGCombine (ISD::INTRINSIC_WO_CHAIN);
238
+
221
239
// Compute derived properties from the register classes.
222
240
computeRegisterProperties (Subtarget.getRegisterInfo ());
223
241
@@ -235,12 +253,6 @@ LoongArchTargetLowering::LoongArchTargetLowering(const TargetMachine &TM,
235
253
setPrefFunctionAlignment (Subtarget.getPrefFunctionAlignment ());
236
254
setPrefLoopAlignment (Subtarget.getPrefLoopAlignment ());
237
255
setMaxBytesForAlignment (Subtarget.getMaxBytesForAlignment ());
238
-
239
- setTargetDAGCombine (ISD::AND);
240
- setTargetDAGCombine (ISD::OR);
241
- setTargetDAGCombine (ISD::SRL);
242
- if (Subtarget.hasExtLSX ())
243
- setTargetDAGCombine (ISD::INTRINSIC_WO_CHAIN);
244
256
}
245
257
246
258
bool LoongArchTargetLowering::isOffsetFoldingLegal (
0 commit comments