@@ -37,6 +37,26 @@ def fplomsbzero : PatLeaf<(fpimm), [{ return (N->getValueAPF().bitcastToAPInt()
37
37
def fplozero : PatLeaf<(fpimm), [{ return (N->getValueAPF().bitcastToAPInt()
38
38
.getZExtValue() & 0xffffffff) == 0; }]>;
39
39
40
+ def CCSIOp : PatLeaf<(cond), [{
41
+ switch (N->get()) {
42
+ default: return true;
43
+ case ISD::SETULT:
44
+ case ISD::SETULE:
45
+ case ISD::SETUGT:
46
+ case ISD::SETUGE: return false;
47
+ }
48
+ }]>;
49
+
50
+ def CCUIOp : PatLeaf<(cond), [{
51
+ switch (N->get()) {
52
+ default: return true;
53
+ case ISD::SETLT:
54
+ case ISD::SETLE:
55
+ case ISD::SETGT:
56
+ case ISD::SETGE: return false;
57
+ }
58
+ }]>;
59
+
40
60
def LOFP32 : SDNodeXForm<fpimm, [{
41
61
// Get a integer immediate from fpimm
42
62
const APInt& imm = N->getValueAPF().bitcastToAPInt();
@@ -62,6 +82,54 @@ def HI32 : SDNodeXForm<imm, [{
62
82
SDLoc(N), MVT::i32);
63
83
}]>;
64
84
85
+ def icond2cc : SDNodeXForm<cond, [{
86
+ VECC::CondCodes cc;
87
+ switch (N->get()) {
88
+ default: llvm_unreachable("Unknown integer condition code!");
89
+ case ISD::SETEQ: cc = VECC::CC_IEQ; break;
90
+ case ISD::SETNE: cc = VECC::CC_INE; break;
91
+ case ISD::SETLT: cc = VECC::CC_IL; break;
92
+ case ISD::SETGT: cc = VECC::CC_IG; break;
93
+ case ISD::SETLE: cc = VECC::CC_ILE; break;
94
+ case ISD::SETGE: cc = VECC::CC_IGE; break;
95
+ case ISD::SETULT: cc = VECC::CC_IL; break;
96
+ case ISD::SETULE: cc = VECC::CC_ILE; break;
97
+ case ISD::SETUGT: cc = VECC::CC_IG; break;
98
+ case ISD::SETUGE: cc = VECC::CC_IGE; break;
99
+ }
100
+ return CurDAG->getTargetConstant(cc, SDLoc(N), MVT::i32);
101
+ }]>;
102
+
103
+ def fcond2cc : SDNodeXForm<cond, [{
104
+ VECC::CondCodes cc;
105
+ switch (N->get()) {
106
+ default: llvm_unreachable("Unknown float condition code!");
107
+ case ISD::SETFALSE: cc = VECC::CC_AF; break;
108
+ case ISD::SETEQ:
109
+ case ISD::SETOEQ: cc = VECC::CC_EQ; break;
110
+ case ISD::SETNE:
111
+ case ISD::SETONE: cc = VECC::CC_NE; break;
112
+ case ISD::SETLT:
113
+ case ISD::SETOLT: cc = VECC::CC_L; break;
114
+ case ISD::SETGT:
115
+ case ISD::SETOGT: cc = VECC::CC_G; break;
116
+ case ISD::SETLE:
117
+ case ISD::SETOLE: cc = VECC::CC_LE; break;
118
+ case ISD::SETGE:
119
+ case ISD::SETOGE: cc = VECC::CC_GE; break;
120
+ case ISD::SETO: cc = VECC::CC_NUM; break;
121
+ case ISD::SETUO: cc = VECC::CC_NAN; break;
122
+ case ISD::SETUEQ: cc = VECC::CC_EQNAN; break;
123
+ case ISD::SETUNE: cc = VECC::CC_NENAN; break;
124
+ case ISD::SETULT: cc = VECC::CC_LNAN; break;
125
+ case ISD::SETUGT: cc = VECC::CC_GNAN; break;
126
+ case ISD::SETULE: cc = VECC::CC_LENAN; break;
127
+ case ISD::SETUGE: cc = VECC::CC_GENAN; break;
128
+ case ISD::SETTRUE: cc = VECC::CC_AT; break;
129
+ }
130
+ return CurDAG->getTargetConstant(cc, SDLoc(N), MVT::i32);
131
+ }]>;
132
+
65
133
// ASX format of memory address
66
134
def MEMri : Operand<iPTR> {
67
135
let PrintMethod = "printMemASXOperand";
@@ -195,6 +263,14 @@ multiclass RRmrr<string opcStr, bits<8>opc, SDNode OpNode,
195
263
{ let cy = 1; let cz = 1; let hasSideEffects = 0; }
196
264
}
197
265
266
+ multiclass RRNDmrr<string opcStr, bits<8>opc,
267
+ RegisterClass RCo, ValueType Tyo,
268
+ RegisterClass RCi, ValueType Tyi> {
269
+ def rr : RR<opc, (outs RCo:$sx), (ins RCi:$sy, RCi:$sz),
270
+ !strconcat(opcStr, " $sx, $sy, $sz")>
271
+ { let cy = 1; let cz = 1; let hasSideEffects = 0; }
272
+ }
273
+
198
274
multiclass RRmri<string opcStr, bits<8>opc, SDNode OpNode,
199
275
RegisterClass RCo, ValueType Tyo,
200
276
RegisterClass RCi, ValueType Tyi, Operand immOp> {
@@ -258,6 +334,18 @@ multiclass RRm<string opcStr, bits<8>opc, SDNode OpNode,
258
334
RRNDmrm<opcStr, opc, RC, Ty, RC, Ty, immOp2>,
259
335
RRNDmim<opcStr, opc, RC, Ty, RC, Ty, immOp, immOp2>;
260
336
337
+ // Used by cmp instruction
338
+ // The order of operands are "$sx, $sy, $sz"
339
+
340
+ multiclass RRNDm<string opcStr, bits<8>opc,
341
+ RegisterClass RC, ValueType Ty,
342
+ Operand immOp, Operand immOp2> :
343
+ RRNDmrr<opcStr, opc, RC, Ty, RC, Ty>,
344
+ //RRNDmir<opcStr, opc, RC, Ty, RC, Ty, immOp>,
345
+ //RRNDmiz<opcStr, opc, RC, Ty, RC, Ty, immOp>,
346
+ RRNDmrm<opcStr, opc, RC, Ty, RC, Ty, immOp2>,
347
+ RRNDmim<opcStr, opc, RC, Ty, RC, Ty, immOp, immOp2>;
348
+
261
349
// Multiclass for RR type instructions
262
350
// Used by sra, sla, sll, and similar instructions
263
351
// The order of operands are "$sx, $sz, $sy"
@@ -274,6 +362,22 @@ multiclass RRIm<string opcStr, bits<8>opc, SDNode OpNode,
274
362
}
275
363
}
276
364
365
+ // Multiclass for RR type instructions
366
+ // Used by cmov instruction
367
+
368
+ let Constraints = "$sx = $sd", DisableEncoding = "$sd" in
369
+ multiclass RRCMOVm<string opcStr, bits<8>opc,
370
+ RegisterClass RC, ValueType Ty, Operand immOp, Operand immOp2> {
371
+ def rm0 : RR<
372
+ opc, (outs I64:$sx), (ins CCOp:$cf, RC:$sy, immOp2:$sz, I64:$sd),
373
+ !strconcat(opcStr, " $sx, (${sz})0, $sy")> {
374
+ let cy = 1;
375
+ let cz = 0;
376
+ let sz{6} = 1;
377
+ let hasSideEffects = 0;
378
+ }
379
+ }
380
+
277
381
// Branch multiclass
278
382
let isBranch = 1, isTerminator = 1, hasDelaySlot = 1 in
279
383
multiclass BCRm<string opcStr, string opcStrAt, bits<8> opc,
@@ -292,6 +396,20 @@ multiclass BCRm<string opcStr, string opcStrAt, bits<8> opc,
292
396
// Instructions
293
397
//===----------------------------------------------------------------------===//
294
398
399
+ // CMOV instructions
400
+ let cx = 0, cw = 0, cw2 = 0 in
401
+ defm CMOVL : RRCMOVm<"cmov.l.${cf}", 0x3B, I64, i64, simm7Op64, uimm6Op64>;
402
+
403
+ let cx = 0, cw = 1, cw2 = 0 in
404
+ defm CMOVW : RRCMOVm<"cmov.w.${cf}", 0x3B, I32, i32, simm7Op64, uimm6Op32>;
405
+
406
+ let cx = 0, cw = 0, cw2 = 1 in
407
+ defm CMOVD : RRCMOVm<"cmov.d.${cf}", 0x3B, I64, f64, simm7Op64, uimm6Op64>;
408
+
409
+ let cx = 0, cw = 1, cw2 = 1 in
410
+ defm CMOVS : RRCMOVm<"cmov.s.${cf}", 0x3B, F32, f32, simm7Op64, uimm6Op32>;
411
+
412
+
295
413
// LEA and LEASL instruction (load 32 bit imm to low or high part)
296
414
let cx = 0 in
297
415
defm LEA : RMm<"lea", 0x06, I64, i64, simm7Op64, simm32Op64>;
@@ -311,11 +429,27 @@ defm ADS : RRm<"adds.w.sx", 0x4A, add, I32, i32, simm7Op32, uimm6Op32>;
311
429
let cx = 1 in
312
430
defm ADSU : RRm<"adds.w.zx", 0x4A, add, I32, i32, simm7Op32, uimm6Op32>;
313
431
314
-
315
432
// ADX instruction
316
433
let cx = 0 in
317
434
defm ADX : RRm<"adds.l", 0x59, add, I64, i64, simm7Op64, uimm6Op64>;
318
435
436
+ // CMP instruction
437
+ let cx = 0 in
438
+ defm CMP : RRNDm<"cmpu.l", 0x55, I64, i64, simm7Op64, uimm6Op64>;
439
+ let cx = 1 in
440
+ defm CMPUW : RRNDm<"cmpu.w", 0x55, I32, i32, simm7Op32, uimm6Op32>;
441
+
442
+ // CPS instruction
443
+ let cx = 0 in
444
+ defm CPS : RRNDm<"cmps.w.sx", 0x7A, I32, i32, simm7Op32, uimm6Op32>;
445
+ let cx = 1 in
446
+ defm CPSU : RRNDm<"cmps.w.zx", 0x7A, I32, i32, simm7Op32, uimm6Op32>;
447
+
448
+ // CPX instruction
449
+ let cx = 0 in
450
+ defm CPX : RRNDm<"cmps.l", 0x6A, I64, i64, simm7Op64, uimm6Op64>;
451
+
452
+
319
453
// 5.3.2.3. Logical Arithmetic Operation Instructions
320
454
321
455
let cx = 0 in {
@@ -324,6 +458,7 @@ let cx = 0 in {
324
458
let isCodeGenOnly = 1 in {
325
459
defm AND32 : RRm<"and", 0x44, and, I32, i32, simm7Op32, uimm6Op32>;
326
460
defm OR32 : RRm<"or", 0x45, or, I32, i32, simm7Op32, uimm6Op32>;
461
+ defm XOR32 : RRm<"xor", 0x46, xor, I32, i32, simm7Op32, uimm6Op32>;
327
462
}
328
463
}
329
464
@@ -340,6 +475,11 @@ defm SLL : RRIm<"sll", 0x65, shl, I64, i64, simm7Op32, uimm6Op64>;
340
475
let cx = 0 in
341
476
defm SLA : RRIm<"sla.w.sx", 0x66, shl, I32, i32, simm7Op32, uimm6Op32>;
342
477
478
+ // FCP instruction
479
+ let cx = 0 in
480
+ defm FCP : RRNDm<"fcmp.d", 0x7E, I64, f64, simm7Op64, uimm6Op64>;
481
+ let cx = 1 in
482
+ defm FCPS : RRNDm<"fcmp.s", 0x7E, F32, f32, simm7Op32, uimm6Op32>;
343
483
344
484
// Load and Store instructions
345
485
// As 1st step, only uses sz and imm32 to represent $addr
@@ -488,6 +628,55 @@ def EXTEND_STACK_GUARD : Pseudo<(outs), (ins),
488
628
"# EXTEND STACK GUARD",
489
629
[]>;
490
630
631
+ // SETCC pattern matches
632
+ //
633
+ // CMP %tmp, lhs, rhs ; compare lhs and rhs
634
+ // or %res, 0, (0)1 ; initialize by 0
635
+ // CMOV %res, (63)0, %tmp ; set 1 if %tmp is true
636
+
637
+ def : Pat<(i32 (setcc i64:$LHS, i64:$RHS, CCSIOp:$cond)),
638
+ (EXTRACT_SUBREG
639
+ (CMOVLrm0 (icond2cc $cond),
640
+ (CPXrr i64:$LHS, i64:$RHS),
641
+ 63,
642
+ (ORim1 0, 0)), sub_i32)>;
643
+
644
+ def : Pat<(i32 (setcc i64:$LHS, i64:$RHS, CCUIOp:$cond)),
645
+ (EXTRACT_SUBREG
646
+ (CMOVLrm0 (icond2cc $cond),
647
+ (CMPrr i64:$LHS, i64:$RHS),
648
+ 63,
649
+ (ORim1 0, 0)), sub_i32)>;
650
+
651
+ def : Pat<(i32 (setcc i32:$LHS, i32:$RHS, CCSIOp:$cond)),
652
+ (EXTRACT_SUBREG
653
+ (CMOVWrm0 (icond2cc $cond),
654
+ (CPSrr i32:$LHS, i32:$RHS),
655
+ 63,
656
+ (ORim1 0, 0)), sub_i32)>;
657
+
658
+ def : Pat<(i32 (setcc i32:$LHS, i32:$RHS, CCUIOp:$cond)),
659
+ (EXTRACT_SUBREG
660
+ (CMOVWrm0 (icond2cc $cond),
661
+ (CMPUWrr i32:$LHS, i32:$RHS),
662
+ 63,
663
+ (ORim1 0, 0)), sub_i32)>;
664
+
665
+ def : Pat<(i32 (setcc f64:$LHS, f64:$RHS, cond:$cond)),
666
+ (EXTRACT_SUBREG
667
+ (CMOVDrm0 (fcond2cc $cond),
668
+ (FCPrr f64:$LHS, f64:$RHS),
669
+ 63,
670
+ (ORim1 0, 0)), sub_i32)>;
671
+
672
+ def : Pat<(i32 (setcc f32:$LHS, f32:$RHS, cond:$cond)),
673
+ (EXTRACT_SUBREG
674
+ (CMOVSrm0 (fcond2cc $cond),
675
+ (FCPSrr f32:$LHS, f32:$RHS),
676
+ 63,
677
+ (ORim1 0, 0)), sub_i32)>;
678
+
679
+
491
680
// Several special pattern matches to optimize code
492
681
493
682
def : Pat<(i32 (and i32:$lhs, 0xff)),
0 commit comments