@@ -277,31 +277,63 @@ class BinOpAIF_AF<bits<8> o, string m, X86TypeInfo t, Register areg,
277
277
let SchedRW = [WriteADC];
278
278
}
279
279
280
- // UnaryOpR - Instructions that read "reg" and write "reg".
281
- class UnaryOpR<bits<8> o, Format f, string m, X86TypeInfo t, list<dag> p>
282
- : ITy<o, f, t, (outs t.RegClass:$dst),
283
- (ins t.RegClass:$src1), m, "$dst", p>, Sched<[WriteALU]>;
284
-
285
- // UnaryOpM - Instructions that read "[mem]" and writes "[mem]".
286
- class UnaryOpM<bits<8> o, Format f, string m, X86TypeInfo t, list<dag> p>
287
- : ITy<o, f, t, (outs), (ins t.MemOperand:$dst), m, "$dst", p>,
288
- Sched<[WriteALURMW]> {
280
+ // UnaryOpR - Instructions that read "reg".
281
+ class UnaryOpR<bits<8> o, Format f, string m, string args, X86TypeInfo t,
282
+ dag out, list<dag> p>
283
+ : ITy<o, f, t, out, (ins t.RegClass:$src), m, args, p>, Sched<[WriteALU]>;
284
+ // UnaryOpR_R - Instructions that read "reg" and write "reg".
285
+ class UnaryOpR_R<bits<8> o, Format f, string m, X86TypeInfo t,
286
+ SDPatternOperator node>
287
+ : UnaryOpR<o, f, m, unaryop_args, t, (outs t.RegClass:$dst),
288
+ [(set t.RegClass:$dst, (node t.RegClass:$src))]>;
289
+ // UnaryOpR_RF - Instructions that read "reg" and write "reg"/EFLAGS.
290
+ class UnaryOpR_RF<bits<8> o, Format f, string m, X86TypeInfo t,
291
+ SDPatternOperator node>
292
+ : UnaryOpR<o, f, m, unaryop_args, t, (outs t.RegClass:$dst),
293
+ [(set t.RegClass:$dst, (node t.RegClass:$src)),
294
+ (implicit EFLAGS)]>, DefEFLAGS;
295
+
296
+ // UnaryOpM - Instructions that read "[mem]".
297
+ class UnaryOpM<bits<8> o, Format f, string m, string args, X86TypeInfo t,
298
+ dag out, list<dag> p>
299
+ : ITy<o, f, t, out, (ins t.MemOperand:$src), m, args, p> {
289
300
let mayLoad = 1;
301
+ }
302
+ // UnaryOpM_M - Instructions that read "[mem]" and writes "[mem]".
303
+ class UnaryOpM_M<bits<8> o, Format f, string m, X86TypeInfo t,
304
+ SDPatternOperator node>
305
+ : UnaryOpM<o, f, m, unaryop_args, t, (outs),
306
+ [(store (node (t.LoadNode addr:$src)), addr:$src)]>,
307
+ Sched<[WriteALURMW]>{
308
+ let mayStore = 1;
309
+ }
310
+ // UnaryOpM_MF - Instructions that read "[mem]" and writes "[mem]"/EFLAGS.
311
+ class UnaryOpM_MF<bits<8> o, Format f, string m, X86TypeInfo t,
312
+ SDPatternOperator node>
313
+ : UnaryOpM<o, f, m, unaryop_args, t, (outs),
314
+ [(store (node (t.LoadNode addr:$src)), addr:$src),
315
+ (implicit EFLAGS)]>, Sched<[WriteALURMW]>, DefEFLAGS {
290
316
let mayStore = 1;
291
317
}
292
318
293
319
//===----------------------------------------------------------------------===//
294
320
// MUL/IMUL and DIV/IDIV Instructions
295
321
//
296
- class MulOpR <bits<8> o, Format f, string m, X86TypeInfo t,
322
+ class MulDivOpR <bits<8> o, Format f, string m, X86TypeInfo t,
297
323
X86FoldableSchedWrite sched, list<dag> p>
298
- : ITy<o, f, t, (outs), (ins t.RegClass:$src), m, "$src", p>, Sched<[sched]>;
324
+ : UnaryOpR<o, f, m, "$src", t, (outs), p> {
325
+ let SchedRW = [sched];
326
+ }
299
327
300
- class MulOpM <bits<8> o, Format f, string m, X86TypeInfo t,
328
+ class MulDivOpM <bits<8> o, Format f, string m, X86TypeInfo t,
301
329
X86FoldableSchedWrite sched, list<dag> p>
302
- : ITy<o, f, t, (outs), (ins t.MemOperand:$src), m,
303
- "$src", p>, SchedLoadReg<sched> {
304
- let mayLoad = 1;
330
+ : UnaryOpM<o, f, m, "$src", t, (outs), p> {
331
+ let SchedRW =
332
+ [sched.Folded,
333
+ // Memory operand.
334
+ ReadDefault, ReadDefault, ReadDefault, ReadDefault, ReadDefault,
335
+ // Register reads (implicit or explicit).
336
+ sched.ReadAfterFold, sched.ReadAfterFold];
305
337
}
306
338
307
339
multiclass Mul<bits<8> o, string m, Format RegMRM, Format MemMRM, SDPatternOperator node> {
@@ -312,23 +344,23 @@ multiclass Mul<bits<8> o, string m, Format RegMRM, Format MemMRM, SDPatternOpera
312
344
// This probably ought to be moved to a def : Pat<> if the
313
345
// syntax can be accepted.
314
346
let Defs = [AL,EFLAGS,AX], Uses = [AL] in
315
- def 8r : MulOpR <o, RegMRM, m, Xi8, WriteIMul8,
347
+ def 8r : MulDivOpR <o, RegMRM, m, Xi8, WriteIMul8,
316
348
[(set AL, (node AL, GR8:$src)), (implicit EFLAGS)]>;
317
349
let Defs = [AX,DX,EFLAGS], Uses = [AX] in
318
- def 16r : MulOpR <o, RegMRM, m, Xi16, WriteIMul16, []>, OpSize16;
350
+ def 16r : MulDivOpR <o, RegMRM, m, Xi16, WriteIMul16, []>, OpSize16;
319
351
let Defs = [EAX,EDX,EFLAGS], Uses = [EAX] in
320
- def 32r : MulOpR <o, RegMRM, m, Xi32, WriteIMul32, []>, OpSize32;
352
+ def 32r : MulDivOpR <o, RegMRM, m, Xi32, WriteIMul32, []>, OpSize32;
321
353
let Defs = [RAX,RDX,EFLAGS], Uses = [RAX] in
322
- def 64r : MulOpR <o, RegMRM, m, Xi64, WriteIMul64, []>;
354
+ def 64r : MulDivOpR <o, RegMRM, m, Xi64, WriteIMul64, []>;
323
355
let Defs = [AL,EFLAGS,AX], Uses = [AL] in
324
- def 8m : MulOpM <o, MemMRM, m, Xi8, WriteIMul8,
356
+ def 8m : MulDivOpM <o, MemMRM, m, Xi8, WriteIMul8,
325
357
[(set AL, (node AL, (loadi8 addr:$src))), (implicit EFLAGS)]>;
326
358
let Defs = [AX,DX,EFLAGS], Uses = [AX] in
327
- def 16m : MulOpM <o, MemMRM, m, Xi16, WriteIMul16, []>, OpSize16;
359
+ def 16m : MulDivOpM <o, MemMRM, m, Xi16, WriteIMul16, []>, OpSize16;
328
360
let Defs = [EAX,EDX,EFLAGS], Uses = [EAX] in
329
- def 32m : MulOpM <o, MemMRM, m, Xi32, WriteIMul32, []>, OpSize32;
361
+ def 32m : MulDivOpM <o, MemMRM, m, Xi32, WriteIMul32, []>, OpSize32;
330
362
let Defs = [RAX,RDX,EFLAGS], Uses = [RAX] in
331
- def 64m : MulOpM <o, MemMRM, m, Xi64, WriteIMul64, []>, Requires<[In64BitMode]>;
363
+ def 64m : MulDivOpM <o, MemMRM, m, Xi64, WriteIMul64, []>, Requires<[In64BitMode]>;
332
364
}
333
365
334
366
defm MUL : Mul<0xF7, "mul", MRM4r, MRM4m, mul>;
@@ -340,21 +372,21 @@ multiclass Div<bits<8> o, string m, Format RegMRM, Format MemMRM> {
340
372
defvar sched32 = !if(!eq(m, "div"), WriteDiv32, WriteIDiv32);
341
373
defvar sched64 = !if(!eq(m, "div"), WriteDiv64, WriteIDiv64);
342
374
let Defs = [AL,AH,EFLAGS], Uses = [AX] in
343
- def 8r : MulOpR <o, RegMRM, m, Xi8, sched8, []>;
375
+ def 8r : MulDivOpR <o, RegMRM, m, Xi8, sched8, []>;
344
376
let Defs = [AX,DX,EFLAGS], Uses = [AX,DX] in
345
- def 16r : MulOpR <o, RegMRM, m, Xi16, sched16, []>, OpSize16;
377
+ def 16r : MulDivOpR <o, RegMRM, m, Xi16, sched16, []>, OpSize16;
346
378
let Defs = [EAX,EDX,EFLAGS], Uses = [EAX,EDX] in
347
- def 32r : MulOpR <o, RegMRM, m, Xi32, sched32, []>, OpSize32;
379
+ def 32r : MulDivOpR <o, RegMRM, m, Xi32, sched32, []>, OpSize32;
348
380
let Defs = [RAX,RDX,EFLAGS], Uses = [RAX,RDX] in
349
- def 64r : MulOpR <o, RegMRM, m, Xi64, sched64, []>;
381
+ def 64r : MulDivOpR <o, RegMRM, m, Xi64, sched64, []>;
350
382
let Defs = [AL,AH,EFLAGS], Uses = [AX] in
351
- def 8m : MulOpM <o, MemMRM, m, Xi8, sched8, []>;
383
+ def 8m : MulDivOpM <o, MemMRM, m, Xi8, sched8, []>;
352
384
let Defs = [AX,DX,EFLAGS], Uses = [AX,DX] in
353
- def 16m : MulOpM <o, MemMRM, m, Xi16, sched16, []>, OpSize16;
385
+ def 16m : MulDivOpM <o, MemMRM, m, Xi16, sched16, []>, OpSize16;
354
386
let Defs = [EAX,EDX,EFLAGS], Uses = [EAX,EDX] in
355
- def 32m : MulOpM <o, MemMRM, m, Xi32, sched32, []>, OpSize32;
387
+ def 32m : MulDivOpM <o, MemMRM, m, Xi32, sched32, []>, OpSize32;
356
388
let Defs = [RAX,RDX,EFLAGS], Uses = [RAX,RDX] in
357
- def 64m : MulOpM <o, MemMRM, m, Xi64, sched64, []>, Requires<[In64BitMode]>;
389
+ def 64m : MulDivOpM <o, MemMRM, m, Xi64, sched64, []>, Requires<[In64BitMode]>;
358
390
}
359
391
let hasSideEffects = 1 in { // so that we don't speculatively execute
360
392
defm DIV: Div<0xF7, "div", MRM6r, MRM6m>;
@@ -426,92 +458,84 @@ def IMUL64rmi32 : IMulOpMI_R<Xi64, WriteIMul64Imm>;
426
458
//===----------------------------------------------------------------------===//
427
459
// INC and DEC Instructions
428
460
//
429
- class INCDECR<Format f, string m, X86TypeInfo t, SDPatternOperator node>
430
- : UnaryOpR<0xFF, f, m, t,
431
- [(set t.RegClass:$dst, EFLAGS, (node t.RegClass:$src1, 1))]>,
432
- DefEFLAGS {
433
- let isConvertibleToThreeAddress = 1; // Can xform into LEA.
461
+ class IncOpR_RF<X86TypeInfo t> : UnaryOpR_RF<0xFF, MRM0r, "inc", t, null_frag> {
462
+ let Pattern = [(set t.RegClass:$dst, EFLAGS,
463
+ (X86add_flag_nocf t.RegClass:$src, 1))];
434
464
}
435
- class INCDECM<Format f, string m, X86TypeInfo t, int num>
436
- : UnaryOpM<0xFF, f, m, t,
437
- [(store (add (t.LoadNode addr:$dst), num), addr:$dst),
438
- (implicit EFLAGS)]>, DefEFLAGS;
439
- // INCDECR_ALT - Instructions like "inc reg" short forms.
440
- class INCDECR_ALT<bits<8> o, string m, X86TypeInfo t>
441
- : UnaryOpR<o, AddRegFrm, m, t, []>, DefEFLAGS {
442
- // Short forms only valid in 32-bit mode. Selected during MCInst lowering.
443
- let Predicates = [Not64BitMode];
465
+ class DecOpR_RF<X86TypeInfo t> : UnaryOpR_RF<0xFF, MRM1r, "dec", t, null_frag> {
466
+ let Pattern = [(set t.RegClass:$dst, EFLAGS,
467
+ (X86sub_flag_nocf t.RegClass:$src, 1))];
444
468
}
445
- let Constraints = "$src1 = $dst" in {
446
- def INC16r_alt : INCDECR_ALT<0x40, "inc", Xi16>, OpSize16;
447
- def INC32r_alt : INCDECR_ALT<0x40, "inc", Xi32>, OpSize32;
448
- def INC8r : INCDECR<MRM0r, "inc", Xi8, X86add_flag_nocf>;
449
- def INC16r : INCDECR<MRM0r, "inc", Xi16, X86add_flag_nocf>, OpSize16;
450
- def INC32r : INCDECR<MRM0r, "inc", Xi32, X86add_flag_nocf>, OpSize32;
451
- def INC64r : INCDECR<MRM0r, "inc", Xi64, X86add_flag_nocf>;
452
- def DEC16r_alt : INCDECR_ALT<0x48, "dec", Xi16>, OpSize16;
453
- def DEC32r_alt : INCDECR_ALT<0x48, "dec", Xi32>, OpSize32;
454
- def DEC8r : INCDECR<MRM1r, "dec", Xi8, X86sub_flag_nocf>;
455
- def DEC16r : INCDECR<MRM1r, "dec", Xi16, X86sub_flag_nocf>, OpSize16;
456
- def DEC32r : INCDECR<MRM1r, "dec", Xi32, X86sub_flag_nocf>, OpSize32;
457
- def DEC64r : INCDECR<MRM1r, "dec", Xi64, X86sub_flag_nocf>;
469
+ class IncOpM_M<X86TypeInfo t> : UnaryOpM_MF<0xFF, MRM0m, "inc", t, null_frag> {
470
+ let Pattern = [(store (add (t.LoadNode addr:$src), 1), addr:$src),
471
+ (implicit EFLAGS)];
472
+ }
473
+ class DecOpM_M<X86TypeInfo t> : UnaryOpM_MF<0xFF, MRM1m, "dec", t, null_frag> {
474
+ let Pattern = [(store (add (t.LoadNode addr:$src), -1), addr:$src),
475
+ (implicit EFLAGS)];
476
+ }
477
+ // IncDec_Alt - Instructions like "inc reg" short forms.
478
+ // Short forms only valid in 32-bit mode. Selected during MCInst lowering.
479
+ class IncDec_Alt<bits<8> o, string m, X86TypeInfo t>
480
+ : UnaryOpR_RF<o, AddRegFrm, m, t, null_frag>, Requires<[Not64BitMode]>;
481
+
482
+ let Constraints = "$src = $dst", isConvertibleToThreeAddress = 1 in {
483
+ def INC16r_alt : IncDec_Alt<0x40, "inc", Xi16>, OpSize16;
484
+ def INC32r_alt : IncDec_Alt<0x40, "inc", Xi32>, OpSize32;
485
+ def DEC16r_alt : IncDec_Alt<0x48, "dec", Xi16>, OpSize16;
486
+ def DEC32r_alt : IncDec_Alt<0x48, "dec", Xi32>, OpSize32;
487
+ def INC8r : IncOpR_RF<Xi8>;
488
+ def INC16r : IncOpR_RF<Xi16>, OpSize16;
489
+ def INC32r : IncOpR_RF<Xi32>, OpSize32;
490
+ def INC64r : IncOpR_RF<Xi64>;
491
+ def DEC8r : DecOpR_RF<Xi8>;
492
+ def DEC16r : DecOpR_RF<Xi16>, OpSize16;
493
+ def DEC32r : DecOpR_RF<Xi32>, OpSize32;
494
+ def DEC64r : DecOpR_RF<Xi64>;
458
495
}
459
496
let Predicates = [UseIncDec] in {
460
- def INC8m : INCDECM<MRM0m, "inc", Xi8, 1 >;
461
- def INC16m : INCDECM<MRM0m, "inc", Xi16, 1 >, OpSize16;
462
- def INC32m : INCDECM<MRM0m, "inc", Xi32, 1 >, OpSize32;
463
- def DEC8m : INCDECM<MRM1m, "dec", Xi8, -1 >;
464
- def DEC16m : INCDECM<MRM1m, "dec", Xi16, -1 >, OpSize16;
465
- def DEC32m : INCDECM<MRM1m, "dec", Xi32, -1 >, OpSize32;
497
+ def INC8m : IncOpM_M< Xi8>;
498
+ def INC16m : IncOpM_M< Xi16>, OpSize16;
499
+ def INC32m : IncOpM_M< Xi32>, OpSize32;
500
+ def DEC8m : DecOpM_M< Xi8>;
501
+ def DEC16m : DecOpM_M< Xi16>, OpSize16;
502
+ def DEC32m : DecOpM_M< Xi32>, OpSize32;
466
503
}
467
504
let Predicates = [UseIncDec, In64BitMode] in {
468
- def INC64m : INCDECM<MRM0m, "inc", Xi64, 1 >;
469
- def DEC64m : INCDECM<MRM1m, "dec", Xi64, -1 >;
505
+ def INC64m : IncOpM_M< Xi64>;
506
+ def DEC64m : DecOpM_M< Xi64>;
470
507
}
471
508
472
509
//===----------------------------------------------------------------------===//
473
510
// NEG and NOT Instructions
474
511
//
475
- class NegOpR<bits<8> o, string m, X86TypeInfo t>
476
- : UnaryOpR<o, MRM3r, m, t,
477
- [(set t.RegClass:$dst, (ineg t.RegClass:$src1)),
478
- (implicit EFLAGS)]>, DefEFLAGS;
479
- class NegOpM<bits<8> o, string m, X86TypeInfo t>
480
- : UnaryOpM<o, MRM3m, m, t,
481
- [(store (ineg (t.LoadNode addr:$dst)), addr:$dst),
482
- (implicit EFLAGS)]>, DefEFLAGS;
483
-
484
- // NOTE: NOT does not set EFLAGS!
485
- class NotOpR<bits<8> o, string m, X86TypeInfo t>
486
- : UnaryOpR<o, MRM2r, m, t, [(set t.RegClass:$dst, (not t.RegClass:$src1))]>;
487
-
488
- class NotOpM<bits<8> o, string m, X86TypeInfo t>
489
- : UnaryOpM<o, MRM2m, m, t,
490
- [(store (not (t.LoadNode addr:$dst)), addr:$dst)]>;
491
-
492
- let Constraints = "$src1 = $dst" in {
493
- def NEG8r : NegOpR<0xF6, "neg", Xi8>;
494
- def NEG16r : NegOpR<0xF7, "neg", Xi16>, OpSize16;
495
- def NEG32r : NegOpR<0xF7, "neg", Xi32>, OpSize32;
496
- def NEG64r : NegOpR<0xF7, "neg", Xi64>;
512
+ class NegOpR_RF<X86TypeInfo t> : UnaryOpR_RF<0xF7, MRM3r, "neg", t, ineg>;
513
+ class NegOpM_MF<X86TypeInfo t> : UnaryOpM_MF<0xF7, MRM3m, "neg", t, ineg>;
514
+
515
+ class NotOpR_R<X86TypeInfo t> : UnaryOpR_R<0xF7, MRM2r, "not", t, not>;
516
+ class NotOpM_M<X86TypeInfo t> : UnaryOpM_M<0xF7, MRM2m, "not", t, not>;
517
+
518
+ let Constraints = "$src = $dst" in {
519
+ def NEG8r : NegOpR_RF<Xi8>;
520
+ def NEG16r : NegOpR_RF<Xi16>, OpSize16;
521
+ def NEG32r : NegOpR_RF<Xi32>, OpSize32;
522
+ def NEG64r : NegOpR_RF<Xi64>;
523
+
524
+ def NOT8r : NotOpR_R<Xi8>;
525
+ def NOT16r : NotOpR_R<Xi16>, OpSize16;
526
+ def NOT32r : NotOpR_R<Xi32>, OpSize32;
527
+ def NOT64r : NotOpR_R<Xi64>;
497
528
}
498
529
499
- def NEG8m : NegOpM<0xF6, "neg", Xi8>;
500
- def NEG16m : NegOpM<0xF7, "neg", Xi16>, OpSize16;
501
- def NEG32m : NegOpM<0xF7, "neg", Xi32>, OpSize32;
502
- def NEG64m : NegOpM<0xF7, "neg", Xi64>, Requires<[In64BitMode]>;
503
-
504
- let Constraints = "$src1 = $dst" in {
505
- def NOT8r : NotOpR<0xF6, "not", Xi8>;
506
- def NOT16r : NotOpR<0xF7, "not", Xi16>, OpSize16;
507
- def NOT32r : NotOpR<0xF7, "not", Xi32>, OpSize32;
508
- def NOT64r : NotOpR<0xF7, "not", Xi64>;
509
- }
530
+ def NEG8m : NegOpM_MF<Xi8>;
531
+ def NEG16m : NegOpM_MF<Xi16>, OpSize16;
532
+ def NEG32m : NegOpM_MF<Xi32>, OpSize32;
533
+ def NEG64m : NegOpM_MF<Xi64>, Requires<[In64BitMode]>;
510
534
511
- def NOT8m : NotOpM<0xF6, "not", Xi8>;
512
- def NOT16m : NotOpM<0xF7, "not", Xi16>, OpSize16;
513
- def NOT32m : NotOpM<0xF7, "not", Xi32>, OpSize32;
514
- def NOT64m : NotOpM<0xF7, "not", Xi64>, Requires<[In64BitMode]>;
535
+ def NOT8m : NotOpM_M< Xi8>;
536
+ def NOT16m : NotOpM_M< Xi16>, OpSize16;
537
+ def NOT32m : NotOpM_M< Xi32>, OpSize32;
538
+ def NOT64m : NotOpM_M< Xi64>, Requires<[In64BitMode]>;
515
539
516
540
/// ArithBinOp_RF - This is an arithmetic binary operator where the pattern is
517
541
/// defined with "(set GPR:$dst, EFLAGS, (...".
0 commit comments