@@ -70,6 +70,47 @@ def mimm : Operand<i32>, PatLeaf<(imm), [{
70
70
let PrintMethod = "printMImmOperand";
71
71
}
72
72
73
+ // simm7fp - Generic fp immediate value.
74
+ def LO7FP : SDNodeXForm<fpimm, [{
75
+ // Get a integer immediate from fpimm
76
+ const APInt& imm = N->getValueAPF().bitcastToAPInt();
77
+ uint64_t val = imm.getSExtValue();
78
+ if (imm.getBitWidth() == 32)
79
+ val <<= 32; // Immediate value of float place at higher bits on VE.
80
+ return CurDAG->getTargetConstant(SignExtend32(val, 7), SDLoc(N), MVT::i32);
81
+ }]>;
82
+ def simm7fp : Operand<i32>, PatLeaf<(fpimm), [{
83
+ const APInt& imm = N->getValueAPF().bitcastToAPInt();
84
+ uint64_t val = imm.getSExtValue();
85
+ if (imm.getBitWidth() == 32)
86
+ val <<= 32; // Immediate value of float place at higher bits on VE.
87
+ return isInt<7>(val);
88
+ }], LO7FP> {
89
+ let DecoderMethod = "DecodeSIMM7";
90
+ }
91
+
92
+ // mimm - Special fp immediate value of sequential bit stream of 0 or 1.
93
+ def MIMMFP : SDNodeXForm<fpimm, [{
94
+ const APInt& Imm = N->getValueAPF().bitcastToAPInt();
95
+ uint64_t Val = Imm.getSExtValue();
96
+ bool M0Flag = isMask_64(Val);
97
+ if (Imm.getBitWidth() == 32)
98
+ Val <<= 32; // Immediate value of float place at higher bits on VE.
99
+ if (M0Flag) {
100
+ // bit 6 : If `(m)0`, 1. Otherwise, 0.
101
+ Val = countLeadingZeros(Val) | 0x40;
102
+ } else
103
+ Val = countLeadingOnes(Val);
104
+ return CurDAG->getTargetConstant(Val, SDLoc(N), MVT::i32);
105
+ }]>;
106
+ def mimmfp : Operand<i32>, PatLeaf<(fpimm), [{
107
+ const APInt& Imm = N->getValueAPF().bitcastToAPInt();
108
+ uint64_t Val = Imm.getSExtValue();
109
+ return isMask_64(Val) ||
110
+ ((Val & (1UL << 63)) && isShiftedMask_64(Val)); }], MIMMFP> {
111
+ let PrintMethod = "printMImmOperand";
112
+ }
113
+
73
114
def simm32 : PatLeaf<(imm), [{ return isInt<32>(N->getSExtValue()); }]>;
74
115
def uimm32 : PatLeaf<(imm), [{ return isUInt<32>(N->getZExtValue()); }]>;
75
116
def lomsbzero : PatLeaf<(imm), [{ return (N->getZExtValue() & 0x80000000)
@@ -357,94 +398,79 @@ def RD_RA : RD_VAL<12>; // Round to Nearest (ties to Away)
357
398
// VE Multiclasses for common instruction formats
358
399
//===----------------------------------------------------------------------===//
359
400
360
- multiclass RRmrr<string opcStr, bits<8>opc,
361
- RegisterClass RCo, ValueType Tyo,
362
- RegisterClass RCi, ValueType Tyi,
363
- SDPatternOperator OpNode=null_frag> {
401
+ // Multiclass for generic RR type instructions
402
+ let hasSideEffects = 0 in
403
+ multiclass RRbm<string opcStr, bits<8>opc,
404
+ RegisterClass RCo, ValueType Tyo,
405
+ RegisterClass RCi, ValueType Tyi,
406
+ SDPatternOperator OpNode = null_frag,
407
+ Operand immOp = simm7, Operand mOp = mimm> {
364
408
def rr : RR<opc, (outs RCo:$sx), (ins RCi:$sy, RCi:$sz),
365
409
!strconcat(opcStr, " $sx, $sy, $sz"),
366
- [(set Tyo:$sx, (OpNode Tyi:$sy, Tyi:$sz))]>
367
- { let cy = 1; let cz = 1; let hasSideEffects = 0; }
368
- }
369
-
370
- multiclass RRmri<string opcStr, bits<8>opc,
371
- RegisterClass RCo, ValueType Tyo,
372
- RegisterClass RCi, ValueType Tyi, Operand immOp,
373
- SDPatternOperator OpNode=null_frag> {
410
+ [(set Tyo:$sx, (OpNode Tyi:$sy, Tyi:$sz))]>;
374
411
// VE calculates (OpNode $sy, $sz), but llvm requires to have immediate
375
412
// in RHS, so we use following definition.
413
+ let cy = 0 in
376
414
def ri : RR<opc, (outs RCo:$sx), (ins RCi:$sz, immOp:$sy),
377
415
!strconcat(opcStr, " $sx, $sy, $sz"),
378
- [(set Tyo:$sx, (OpNode Tyi:$sz, (Tyi simm7:$sy)))]>
379
- { let cy = 0; let cz = 1; let hasSideEffects = 0; }
380
- }
381
-
382
- multiclass RRmir<string opcStr, bits<8>opc,
383
- RegisterClass RCo, ValueType Tyo,
384
- RegisterClass RCi, ValueType Tyi, Operand immOp,
385
- SDPatternOperator OpNode=null_frag> {
386
- def ri : RR<opc, (outs RCo:$sx), (ins immOp:$sy, RCi:$sz),
416
+ [(set Tyo:$sx, (OpNode Tyi:$sz, (Tyi immOp:$sy)))]>;
417
+ let cz = 0 in
418
+ def rm : RR<opc, (outs RCo:$sx), (ins RCi:$sy, mOp:$sz),
387
419
!strconcat(opcStr, " $sx, $sy, $sz"),
388
- [(set Tyo:$sx, (OpNode (Tyi simm7:$sy), Tyi:$sz))]>
389
- { let cy = 0; let cz = 1; let hasSideEffects = 0; }
420
+ [(set Tyo:$sx, (OpNode Tyi:$sy, (Tyi mOp:$sz)))]>;
421
+ let cy = 0, cz = 0 in
422
+ def im : RR<opc, (outs RCo:$sx), (ins immOp:$sy, mOp:$sz),
423
+ !strconcat(opcStr, " $sx, $sy, $sz"),
424
+ [(set Tyo:$sx, (OpNode (Tyi immOp:$sy), (Tyi mOp:$sz)))]>;
390
425
}
391
426
392
- multiclass RRNDmrm<string opcStr, bits<8>opc,
393
- RegisterClass RCo, ValueType Tyo,
394
- RegisterClass RCi, ValueType Tyi, Operand mOp,
395
- SDPatternOperator OpNode=null_frag> {
396
- let cy = 1, cz = 0, hasSideEffects = 0 in
427
+ // Multiclass for non-commutative RR type instructions
428
+ let hasSideEffects = 0 in
429
+ multiclass RRNCbm<string opcStr, bits<8>opc,
430
+ RegisterClass RCo, ValueType Tyo,
431
+ RegisterClass RCi, ValueType Tyi,
432
+ SDPatternOperator OpNode = null_frag,
433
+ Operand immOp = simm7, Operand mOp = mimm> {
434
+ def rr : RR<opc, (outs RCo:$sx), (ins RCi:$sy, RCi:$sz),
435
+ !strconcat(opcStr, " $sx, $sy, $sz"),
436
+ [(set Tyo:$sx, (OpNode Tyi:$sy, Tyi:$sz))]>;
437
+ let cy = 0 in
438
+ def ir : RR<opc, (outs RCo:$sx), (ins immOp:$sy, RCi:$sz),
439
+ !strconcat(opcStr, " $sx, $sy, $sz"),
440
+ [(set Tyo:$sx, (OpNode (Tyi immOp:$sy), Tyi:$sz))]>;
441
+ let cz = 0 in
397
442
def rm : RR<opc, (outs RCo:$sx), (ins RCi:$sy, mOp:$sz),
398
443
!strconcat(opcStr, " $sx, $sy, $sz"),
399
444
[(set Tyo:$sx, (OpNode Tyi:$sy, (Tyi mOp:$sz)))]>;
400
- }
401
-
402
- multiclass RRNDmim<string opcStr, bits<8>opc,
403
- RegisterClass RCo, ValueType Tyo,
404
- RegisterClass RCi, ValueType Tyi,
405
- Operand immOp, Operand mOp,
406
- SDPatternOperator OpNode=null_frag> {
407
- let cy = 0, cz = 0, hasSideEffects = 0 in
445
+ let cy = 0, cz = 0 in
408
446
def im : RR<opc, (outs RCo:$sx), (ins immOp:$sy, mOp:$sz),
409
447
!strconcat(opcStr, " $sx, $sy, $sz"),
410
448
[(set Tyo:$sx, (OpNode (Tyi immOp:$sy), (Tyi mOp:$sz)))]>;
411
449
}
412
450
413
- // Used by add, mul, div, and similar commutative instructions
414
- // The order of operands are "$sx, $sy, $sz"
415
-
451
+ // Generic RR multiclass with 2 arguments.
452
+ // e.g. ADDUL, ADDSWSX, ADDSWZX, and etc.
416
453
multiclass RRm<string opcStr, bits<8>opc,
417
454
RegisterClass RC, ValueType Ty,
418
455
SDPatternOperator OpNode = null_frag,
419
456
Operand immOp = simm7, Operand mOp = mimm> :
420
- RRmrr<opcStr, opc, RC, Ty, RC, Ty, OpNode>,
421
- RRmri<opcStr, opc, RC, Ty, RC, Ty, immOp, OpNode>,
422
- RRNDmrm<opcStr, opc, RC, Ty, RC, Ty, mOp, OpNode>,
423
- RRNDmim<opcStr, opc, RC, Ty, RC, Ty, immOp, mOp, OpNode>;
424
-
425
- // Used by sub, and similar not commutative instructions
426
- // The order of operands are "$sx, $sy, $sz"
457
+ RRbm<opcStr, opc, RC, Ty, RC, Ty, OpNode, immOp, mOp>;
427
458
459
+ // Generic RR multiclass for non-commutative instructions with 2 arguments.
460
+ // e.g. SUBUL, SUBUW, SUBSWSX, and etc.
428
461
multiclass RRNCm<string opcStr, bits<8>opc,
429
- RegisterClass RC, ValueType Ty,
430
- SDPatternOperator OpNode = null_frag,
431
- Operand immOp = simm7, Operand mOp = mimm> :
432
- RRmrr<opcStr, opc, RC, Ty, RC, Ty, OpNode>,
433
- RRmir<opcStr, opc, RC, Ty, RC, Ty, immOp, OpNode>,
434
- RRNDmrm<opcStr, opc, RC, Ty, RC, Ty, mOp, OpNode>,
435
- RRNDmim<opcStr, opc, RC, Ty, RC, Ty, immOp, mOp, OpNode>;
436
-
437
- // Used by fadd, fsub, and similar floating point instructions
438
- // The order of operands are "$sx, $sy, $sz"
462
+ RegisterClass RC, ValueType Ty,
463
+ SDPatternOperator OpNode = null_frag,
464
+ Operand immOp = simm7, Operand mOp = mimm> :
465
+ RRNCbm<opcStr, opc, RC, Ty, RC, Ty, OpNode, immOp, mOp>;
439
466
467
+ // Generic RR multiclass for floating point instructions with 2 arguments.
468
+ // e.g. FADDD, FADDS, FSUBD, and etc.
440
469
multiclass RRFm<string opcStr, bits<8>opc,
441
- RegisterClass RC, ValueType Ty,
442
- SDPatternOperator OpNode = null_frag,
443
- Operand immOp = simm7, Operand mOp = mimm> :
444
- RRmrr<opcStr, opc, RC, Ty, RC, Ty, OpNode>,
445
- RRmir<opcStr, opc, RC, Ty, RC, Ty, immOp, null_frag>,
446
- RRNDmrm<opcStr, opc, RC, Ty, RC, Ty, mOp, null_frag>,
447
- RRNDmim<opcStr, opc, RC, Ty, RC, Ty, immOp, mOp, null_frag>;
470
+ RegisterClass RC, ValueType Ty,
471
+ SDPatternOperator OpNode = null_frag,
472
+ Operand immOp = simm7fp, Operand mOp = mimmfp> :
473
+ RRNCbm<opcStr, opc, RC, Ty, RC, Ty, OpNode, immOp, mOp>;
448
474
449
475
// Generic RR multiclass for shift instructions with 2 arguments.
450
476
// e.g. SLL, SRL, SLAWSX, and etc.
0 commit comments