@@ -223,61 +223,67 @@ def ROT64L2R_imm8 : SDNodeXForm<imm, [{
223
223
224
224
// NOTE: We use WriteShift for these rotates as they avoid the stalls
225
225
// of many of the older x86 rotate instructions.
226
- multiclass bmi_rotate<string asm, RegisterClass RC, X86MemOperand x86memop,
227
- string Suffix = ""> {
228
- let hasSideEffects = 0 in {
229
- def ri#Suffix : Ii8<0xF0, MRMSrcReg, (outs RC:$dst), (ins RC:$src1, u8imm:$src2),
230
- !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"), []>,
231
- TA, XD, VEX, Sched<[WriteShift]>;
232
- let mayLoad = 1 in
233
- def mi#Suffix : Ii8<0xF0, MRMSrcMem, (outs RC:$dst),
234
- (ins x86memop:$src1, u8imm:$src2),
235
- !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"), []>,
236
- TA, XD, VEX, Sched<[WriteShiftLd]>;
226
+ class RorXri<X86TypeInfo t>
227
+ : ITy<0xF0, MRMSrcReg, t, (outs t.RegClass:$dst), (ins t.RegClass:$src1, u8imm:$src2),
228
+ "rorx", binop_ndd_args, []>, TA, XD, Sched<[WriteShift]> {
229
+ let ImmT = Imm8;
237
230
}
231
+ class RorXmi<X86TypeInfo t>
232
+ : ITy<0xF0, MRMSrcMem, t, (outs t.RegClass:$dst), (ins t.MemOperand:$src1, u8imm:$src2),
233
+ "rorx", binop_ndd_args, []>, TA, XD, Sched<[WriteShiftLd]> {
234
+ let ImmT = Imm8;
235
+ let mayLoad = 1;
238
236
}
239
237
240
- multiclass bmi_shift<string asm, RegisterClass RC, X86MemOperand x86memop,
241
- string Suffix = ""> {
242
- let hasSideEffects = 0 in {
243
- def rr#Suffix : I<0xF7, MRMSrcReg4VOp3, (outs RC:$dst), (ins RC:$src1, RC:$src2),
244
- !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"), []>,
245
- VEX, Sched<[WriteShift]>;
246
- let mayLoad = 1 in
247
- def rm#Suffix : I<0xF7, MRMSrcMem4VOp3,
248
- (outs RC:$dst), (ins x86memop:$src1, RC:$src2),
249
- !strconcat(asm, "\t{$src2, $src1, $dst|$dst, $src1, $src2}"), []>,
250
- VEX, Sched<[WriteShift.Folded,
251
- // x86memop:$src1
252
- ReadDefault, ReadDefault, ReadDefault, ReadDefault,
253
- ReadDefault,
254
- // RC:$src2
255
- WriteShift.ReadAfterFold]>;
256
- }
238
+ multiclass RorX<X86TypeInfo t> {
239
+ let Predicates = [HasBMI2, NoEGPR] in {
240
+ def ri : RorXri<t>, VEX;
241
+ def mi : RorXmi<t>, VEX;
242
+ }
243
+ let Predicates = [HasBMI2, HasEGPR, In64BitMode] in {
244
+ def ri_EVEX : RorXri<t>, EVEX;
245
+ def mi_EVEX : RorXmi<t>, EVEX;
246
+ }
257
247
}
258
248
259
- let Predicates = [HasBMI2, NoEGPR] in {
260
- defm RORX32 : bmi_rotate<"rorx{l}", GR32, i32mem>;
261
- defm RORX64 : bmi_rotate<"rorx{q}", GR64, i64mem>, REX_W;
262
- defm SARX32 : bmi_shift<"sarx{l}", GR32, i32mem>, T8, XS;
263
- defm SARX64 : bmi_shift<"sarx{q}", GR64, i64mem>, T8, XS, REX_W;
264
- defm SHRX32 : bmi_shift<"shrx{l}", GR32, i32mem>, T8, XD;
265
- defm SHRX64 : bmi_shift<"shrx{q}", GR64, i64mem>, T8, XD, REX_W;
266
- defm SHLX32 : bmi_shift<"shlx{l}", GR32, i32mem>, T8, PD;
267
- defm SHLX64 : bmi_shift<"shlx{q}", GR64, i64mem>, T8, PD, REX_W;
249
+ defm RORX32: RorX<Xi32>;
250
+ defm RORX64: RorX<Xi64>;
251
+
252
+ class ShiftXrr<string m, X86TypeInfo t>
253
+ : ITy<0xF7, MRMSrcReg4VOp3, t, (outs t.RegClass:$dst), (ins t.RegClass:$src1, t.RegClass:$src2),
254
+ m, binop_ndd_args, []>, T8, Sched<[WriteShift]>;
255
+
256
+ class ShiftXrm<string m, X86TypeInfo t>
257
+ : ITy<0xF7, MRMSrcMem4VOp3, t, (outs t.RegClass:$dst), (ins t.MemOperand:$src1, t.RegClass:$src2),
258
+ m, binop_ndd_args, []>, T8,
259
+ Sched<[WriteShift.Folded,
260
+ // x86memop:$src1
261
+ ReadDefault, ReadDefault, ReadDefault, ReadDefault,
262
+ ReadDefault,
263
+ // RC:$src2
264
+ WriteShift.ReadAfterFold]> {
265
+ let mayLoad = 1;
268
266
}
269
267
270
- let Predicates = [HasBMI2, HasEGPR, In64BitMode] in {
271
- defm RORX32 : bmi_rotate<"rorx{l}", GR32, i32mem, "_EVEX">, EVEX;
272
- defm RORX64 : bmi_rotate<"rorx{q}", GR64, i64mem, "_EVEX">, REX_W, EVEX;
273
- defm SARX32 : bmi_shift<"sarx{l}", GR32, i32mem, "_EVEX">, T8, XS, EVEX;
274
- defm SARX64 : bmi_shift<"sarx{q}", GR64, i64mem, "_EVEX">, T8, XS, REX_W, EVEX;
275
- defm SHRX32 : bmi_shift<"shrx{l}", GR32, i32mem, "_EVEX">, T8, XD, EVEX;
276
- defm SHRX64 : bmi_shift<"shrx{q}", GR64, i64mem, "_EVEX">, T8, XD, REX_W, EVEX;
277
- defm SHLX32 : bmi_shift<"shlx{l}", GR32, i32mem, "_EVEX">, T8, PD, EVEX;
278
- defm SHLX64 : bmi_shift<"shlx{q}", GR64, i64mem, "_EVEX">, T8, PD, REX_W, EVEX;
268
+
269
+ multiclass ShiftX<string m, X86TypeInfo t> {
270
+ let Predicates = [HasBMI2, NoEGPR] in {
271
+ def rr : ShiftXrr<m, t>, VEX;
272
+ def rm : ShiftXrm<m, t>, VEX;
273
+ }
274
+ let Predicates = [HasBMI2, HasEGPR, In64BitMode] in {
275
+ def rr_EVEX : ShiftXrr<m, t>, EVEX;
276
+ def rm_EVEX : ShiftXrm<m, t>, EVEX;
277
+ }
279
278
}
280
279
280
+ defm SARX32: ShiftX<"sarx", Xi32>, XS;
281
+ defm SARX64: ShiftX<"sarx", Xi64>, XS;
282
+ defm SHRX32: ShiftX<"shrx", Xi32>, XD;
283
+ defm SHRX64: ShiftX<"shrx", Xi64>, XD;
284
+ defm SHLX32: ShiftX<"shlx", Xi32>, PD;
285
+ defm SHLX64: ShiftX<"shlx", Xi64>, PD;
286
+
281
287
let Predicates = [HasBMI2] in {
282
288
// Prefer RORX which is non-destructive and doesn't update EFLAGS.
283
289
let AddedComplexity = 10 in {
0 commit comments