@@ -223,61 +223,67 @@ def ROT64L2R_imm8 : SDNodeXForm<imm, [{
223223
224224// NOTE: We use WriteShift for these rotates as they avoid the stalls
225225// 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;
237230}
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;
238236}
239237
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+ }
257247}
258248
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;
268266}
269267
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+ }
279278}
280279
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+
281287let Predicates = [HasBMI2] in {
282288 // Prefer RORX which is non-destructive and doesn't update EFLAGS.
283289 let AddedComplexity = 10 in {
0 commit comments