File indexing completed on 2026-05-10 08:43:23
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef LLVM_CODEGEN_GLOBALISEL_GENERICMACHINEINSTRS_H
0015 #define LLVM_CODEGEN_GLOBALISEL_GENERICMACHINEINSTRS_H
0016
0017 #include "llvm/ADT/APInt.h"
0018 #include "llvm/CodeGen/MachineInstr.h"
0019 #include "llvm/CodeGen/MachineMemOperand.h"
0020 #include "llvm/CodeGen/TargetOpcodes.h"
0021 #include "llvm/IR/Constants.h"
0022 #include "llvm/IR/Instructions.h"
0023 #include "llvm/Support/Casting.h"
0024
0025 namespace llvm {
0026
0027
0028 class GenericMachineInstr : public MachineInstr {
0029 constexpr static unsigned PoisonFlags = NoUWrap | NoSWrap | NoUSWrap |
0030 IsExact | Disjoint | NonNeg |
0031 FmNoNans | FmNoInfs | SameSign;
0032
0033 public:
0034 GenericMachineInstr() = delete;
0035
0036
0037
0038 Register getReg(unsigned Idx) const { return getOperand(Idx).getReg(); }
0039
0040 static bool classof(const MachineInstr *MI) {
0041 return isPreISelGenericOpcode(MI->getOpcode());
0042 }
0043
0044 bool hasPoisonGeneratingFlags() const { return getFlags() & PoisonFlags; }
0045
0046 void dropPoisonGeneratingFlags() {
0047 clearFlags(PoisonFlags);
0048 assert(!hasPoisonGeneratingFlags());
0049 }
0050 };
0051
0052
0053 class GMemOperation : public GenericMachineInstr {
0054 public:
0055
0056 MachineMemOperand &getMMO() const { return **memoperands_begin(); }
0057
0058
0059 bool isAtomic() const { return getMMO().isAtomic(); }
0060
0061 bool isVolatile() const { return getMMO().isVolatile(); }
0062
0063 bool isSimple() const { return !isAtomic() && !isVolatile(); }
0064
0065
0066
0067 bool isUnordered() const { return getMMO().isUnordered(); }
0068
0069
0070 LocationSize getMemSize() const { return getMMO().getSize(); }
0071
0072 LocationSize getMemSizeInBits() const { return getMMO().getSizeInBits(); }
0073
0074 static bool classof(const MachineInstr *MI) {
0075 return GenericMachineInstr::classof(MI) && MI->hasOneMemOperand();
0076 }
0077 };
0078
0079
0080
0081 class GLoadStore : public GMemOperation {
0082 public:
0083
0084 Register getPointerReg() const { return getOperand(1).getReg(); }
0085
0086 static bool classof(const MachineInstr *MI) {
0087 switch (MI->getOpcode()) {
0088 case TargetOpcode::G_LOAD:
0089 case TargetOpcode::G_STORE:
0090 case TargetOpcode::G_ZEXTLOAD:
0091 case TargetOpcode::G_SEXTLOAD:
0092 return true;
0093 default:
0094 return false;
0095 }
0096 }
0097 };
0098
0099
0100
0101
0102 class GIndexedLoad : public GMemOperation {
0103 public:
0104
0105 Register getDstReg() const { return getOperand(0).getReg(); }
0106
0107 Register getWritebackReg() const { return getOperand(1).getReg(); }
0108
0109 Register getBaseReg() const { return getOperand(2).getReg(); }
0110
0111 Register getOffsetReg() const { return getOperand(3).getReg(); }
0112
0113 bool isPre() const { return getOperand(4).getImm() == 1; }
0114 bool isPost() const { return !isPre(); }
0115
0116 static bool classof(const MachineInstr *MI) {
0117 return MI->getOpcode() == TargetOpcode::G_INDEXED_LOAD;
0118 }
0119 };
0120
0121
0122 class GIndexedExtLoad : public GIndexedLoad {
0123 public:
0124 static bool classof(const MachineInstr *MI) {
0125 return MI->getOpcode() == TargetOpcode::G_INDEXED_SEXTLOAD ||
0126 MI->getOpcode() == TargetOpcode::G_INDEXED_ZEXTLOAD;
0127 }
0128 };
0129
0130
0131 class GIndexedAnyExtLoad : public GIndexedLoad {
0132 public:
0133 static bool classof(const MachineInstr *MI) {
0134 switch (MI->getOpcode()) {
0135 case TargetOpcode::G_INDEXED_LOAD:
0136 case TargetOpcode::G_INDEXED_ZEXTLOAD:
0137 case TargetOpcode::G_INDEXED_SEXTLOAD:
0138 return true;
0139 default:
0140 return false;
0141 }
0142 }
0143 };
0144
0145
0146 class GIndexedZExtLoad : GIndexedExtLoad {
0147 public:
0148 static bool classof(const MachineInstr *MI) {
0149 return MI->getOpcode() == TargetOpcode::G_INDEXED_ZEXTLOAD;
0150 }
0151 };
0152
0153
0154 class GIndexedSExtLoad : GIndexedExtLoad {
0155 public:
0156 static bool classof(const MachineInstr *MI) {
0157 return MI->getOpcode() == TargetOpcode::G_INDEXED_SEXTLOAD;
0158 }
0159 };
0160
0161
0162 class GIndexedStore : public GMemOperation {
0163 public:
0164
0165 Register getWritebackReg() const { return getOperand(0).getReg(); }
0166
0167 Register getValueReg() const { return getOperand(1).getReg(); }
0168
0169 Register getBaseReg() const { return getOperand(2).getReg(); }
0170
0171 Register getOffsetReg() const { return getOperand(3).getReg(); }
0172
0173 bool isPre() const { return getOperand(4).getImm() == 1; }
0174 bool isPost() const { return !isPre(); }
0175
0176 static bool classof(const MachineInstr *MI) {
0177 return MI->getOpcode() == TargetOpcode::G_INDEXED_STORE;
0178 }
0179 };
0180
0181
0182 class GAnyLoad : public GLoadStore {
0183 public:
0184
0185 Register getDstReg() const { return getOperand(0).getReg(); }
0186
0187
0188 const MDNode *getRanges() const {
0189 return getMMO().getRanges();
0190 }
0191
0192 static bool classof(const MachineInstr *MI) {
0193 switch (MI->getOpcode()) {
0194 case TargetOpcode::G_LOAD:
0195 case TargetOpcode::G_ZEXTLOAD:
0196 case TargetOpcode::G_SEXTLOAD:
0197 return true;
0198 default:
0199 return false;
0200 }
0201 }
0202 };
0203
0204
0205 class GLoad : public GAnyLoad {
0206 public:
0207 static bool classof(const MachineInstr *MI) {
0208 return MI->getOpcode() == TargetOpcode::G_LOAD;
0209 }
0210 };
0211
0212
0213 class GExtLoad : public GAnyLoad {
0214 public:
0215 static bool classof(const MachineInstr *MI) {
0216 return MI->getOpcode() == TargetOpcode::G_SEXTLOAD ||
0217 MI->getOpcode() == TargetOpcode::G_ZEXTLOAD;
0218 }
0219 };
0220
0221
0222 class GSExtLoad : public GExtLoad {
0223 public:
0224 static bool classof(const MachineInstr *MI) {
0225 return MI->getOpcode() == TargetOpcode::G_SEXTLOAD;
0226 }
0227 };
0228
0229
0230 class GZExtLoad : public GExtLoad {
0231 public:
0232 static bool classof(const MachineInstr *MI) {
0233 return MI->getOpcode() == TargetOpcode::G_ZEXTLOAD;
0234 }
0235 };
0236
0237
0238 class GStore : public GLoadStore {
0239 public:
0240
0241 Register getValueReg() const { return getOperand(0).getReg(); }
0242
0243 static bool classof(const MachineInstr *MI) {
0244 return MI->getOpcode() == TargetOpcode::G_STORE;
0245 }
0246 };
0247
0248
0249 class GUnmerge : public GenericMachineInstr {
0250 public:
0251
0252 unsigned getNumDefs() const { return getNumOperands() - 1; }
0253
0254 Register getSourceReg() const { return getOperand(getNumDefs()).getReg(); }
0255
0256 static bool classof(const MachineInstr *MI) {
0257 return MI->getOpcode() == TargetOpcode::G_UNMERGE_VALUES;
0258 }
0259 };
0260
0261
0262
0263
0264 class GMergeLikeInstr : public GenericMachineInstr {
0265 public:
0266
0267 unsigned getNumSources() const { return getNumOperands() - 1; }
0268
0269 Register getSourceReg(unsigned I) const { return getReg(I + 1); }
0270
0271 static bool classof(const MachineInstr *MI) {
0272 switch (MI->getOpcode()) {
0273 case TargetOpcode::G_MERGE_VALUES:
0274 case TargetOpcode::G_CONCAT_VECTORS:
0275 case TargetOpcode::G_BUILD_VECTOR:
0276 return true;
0277 default:
0278 return false;
0279 }
0280 }
0281 };
0282
0283
0284 class GMerge : public GMergeLikeInstr {
0285 public:
0286 static bool classof(const MachineInstr *MI) {
0287 return MI->getOpcode() == TargetOpcode::G_MERGE_VALUES;
0288 }
0289 };
0290
0291
0292 class GConcatVectors : public GMergeLikeInstr {
0293 public:
0294 static bool classof(const MachineInstr *MI) {
0295 return MI->getOpcode() == TargetOpcode::G_CONCAT_VECTORS;
0296 }
0297 };
0298
0299
0300 class GBuildVector : public GMergeLikeInstr {
0301 public:
0302 static bool classof(const MachineInstr *MI) {
0303 return MI->getOpcode() == TargetOpcode::G_BUILD_VECTOR;
0304 }
0305 };
0306
0307
0308 class GBuildVectorTrunc : public GMergeLikeInstr {
0309 public:
0310 static bool classof(const MachineInstr *MI) {
0311 return MI->getOpcode() == TargetOpcode::G_BUILD_VECTOR_TRUNC;
0312 }
0313 };
0314
0315
0316 class GShuffleVector : public GenericMachineInstr {
0317 public:
0318 Register getSrc1Reg() const { return getOperand(1).getReg(); }
0319 Register getSrc2Reg() const { return getOperand(2).getReg(); }
0320 ArrayRef<int> getMask() const { return getOperand(3).getShuffleMask(); }
0321
0322 static bool classof(const MachineInstr *MI) {
0323 return MI->getOpcode() == TargetOpcode::G_SHUFFLE_VECTOR;
0324 }
0325 };
0326
0327
0328 class GPtrAdd : public GenericMachineInstr {
0329 public:
0330 Register getBaseReg() const { return getReg(1); }
0331 Register getOffsetReg() const { return getReg(2); }
0332
0333 static bool classof(const MachineInstr *MI) {
0334 return MI->getOpcode() == TargetOpcode::G_PTR_ADD;
0335 }
0336 };
0337
0338
0339 class GImplicitDef : public GenericMachineInstr {
0340 public:
0341 static bool classof(const MachineInstr *MI) {
0342 return MI->getOpcode() == TargetOpcode::G_IMPLICIT_DEF;
0343 }
0344 };
0345
0346
0347 class GSelect : public GenericMachineInstr {
0348 public:
0349 Register getCondReg() const { return getReg(1); }
0350 Register getTrueReg() const { return getReg(2); }
0351 Register getFalseReg() const { return getReg(3); }
0352
0353 static bool classof(const MachineInstr *MI) {
0354 return MI->getOpcode() == TargetOpcode::G_SELECT;
0355 }
0356 };
0357
0358
0359 class GAnyCmp : public GenericMachineInstr {
0360 public:
0361 CmpInst::Predicate getCond() const {
0362 return static_cast<CmpInst::Predicate>(getOperand(1).getPredicate());
0363 }
0364 Register getLHSReg() const { return getReg(2); }
0365 Register getRHSReg() const { return getReg(3); }
0366
0367 static bool classof(const MachineInstr *MI) {
0368 return MI->getOpcode() == TargetOpcode::G_ICMP ||
0369 MI->getOpcode() == TargetOpcode::G_FCMP;
0370 }
0371 };
0372
0373
0374 class GICmp : public GAnyCmp {
0375 public:
0376 static bool classof(const MachineInstr *MI) {
0377 return MI->getOpcode() == TargetOpcode::G_ICMP;
0378 }
0379 };
0380
0381
0382 class GFCmp : public GAnyCmp {
0383 public:
0384 static bool classof(const MachineInstr *MI) {
0385 return MI->getOpcode() == TargetOpcode::G_FCMP;
0386 }
0387 };
0388
0389
0390
0391
0392
0393
0394 class GBinOpCarryOut : public GenericMachineInstr {
0395 public:
0396 Register getDstReg() const { return getReg(0); }
0397 Register getCarryOutReg() const { return getReg(1); }
0398 MachineOperand &getLHS() { return getOperand(2); }
0399 MachineOperand &getRHS() { return getOperand(3); }
0400 Register getLHSReg() const { return getOperand(2).getReg(); }
0401 Register getRHSReg() const { return getOperand(3).getReg(); }
0402
0403 static bool classof(const MachineInstr *MI) {
0404 switch (MI->getOpcode()) {
0405 case TargetOpcode::G_UADDO:
0406 case TargetOpcode::G_SADDO:
0407 case TargetOpcode::G_USUBO:
0408 case TargetOpcode::G_SSUBO:
0409 case TargetOpcode::G_UADDE:
0410 case TargetOpcode::G_SADDE:
0411 case TargetOpcode::G_USUBE:
0412 case TargetOpcode::G_SSUBE:
0413 case TargetOpcode::G_UMULO:
0414 case TargetOpcode::G_SMULO:
0415 return true;
0416 default:
0417 return false;
0418 }
0419 }
0420 };
0421
0422
0423
0424
0425
0426
0427 class GAddSubCarryOut : public GBinOpCarryOut {
0428 public:
0429 bool isAdd() const {
0430 switch (getOpcode()) {
0431 case TargetOpcode::G_UADDO:
0432 case TargetOpcode::G_SADDO:
0433 case TargetOpcode::G_UADDE:
0434 case TargetOpcode::G_SADDE:
0435 return true;
0436 default:
0437 return false;
0438 }
0439 }
0440 bool isSub() const { return !isAdd(); }
0441
0442 bool isSigned() const {
0443 switch (getOpcode()) {
0444 case TargetOpcode::G_SADDO:
0445 case TargetOpcode::G_SSUBO:
0446 case TargetOpcode::G_SADDE:
0447 case TargetOpcode::G_SSUBE:
0448 return true;
0449 default:
0450 return false;
0451 }
0452 }
0453 bool isUnsigned() const { return !isSigned(); }
0454
0455 static bool classof(const MachineInstr *MI) {
0456 switch (MI->getOpcode()) {
0457 case TargetOpcode::G_UADDO:
0458 case TargetOpcode::G_SADDO:
0459 case TargetOpcode::G_USUBO:
0460 case TargetOpcode::G_SSUBO:
0461 case TargetOpcode::G_UADDE:
0462 case TargetOpcode::G_SADDE:
0463 case TargetOpcode::G_USUBE:
0464 case TargetOpcode::G_SSUBE:
0465 return true;
0466 default:
0467 return false;
0468 }
0469 }
0470 };
0471
0472
0473
0474 class GAddCarryOut : public GBinOpCarryOut {
0475 public:
0476 bool isSigned() const { return getOpcode() == TargetOpcode::G_SADDO; }
0477
0478 static bool classof(const MachineInstr *MI) {
0479 switch (MI->getOpcode()) {
0480 case TargetOpcode::G_UADDO:
0481 case TargetOpcode::G_SADDO:
0482 return true;
0483 default:
0484 return false;
0485 }
0486 }
0487 };
0488
0489
0490
0491 class GSubCarryOut : public GBinOpCarryOut {
0492 public:
0493 bool isSigned() const { return getOpcode() == TargetOpcode::G_SSUBO; }
0494
0495 static bool classof(const MachineInstr *MI) {
0496 switch (MI->getOpcode()) {
0497 case TargetOpcode::G_USUBO:
0498 case TargetOpcode::G_SSUBO:
0499 return true;
0500 default:
0501 return false;
0502 }
0503 }
0504 };
0505
0506
0507
0508 class GAddSubCarryInOut : public GAddSubCarryOut {
0509 public:
0510 Register getCarryInReg() const { return getReg(4); }
0511
0512 static bool classof(const MachineInstr *MI) {
0513 switch (MI->getOpcode()) {
0514 case TargetOpcode::G_UADDE:
0515 case TargetOpcode::G_SADDE:
0516 case TargetOpcode::G_USUBE:
0517 case TargetOpcode::G_SSUBE:
0518 return true;
0519 default:
0520 return false;
0521 }
0522 }
0523 };
0524
0525
0526 class GIntrinsic final : public GenericMachineInstr {
0527 public:
0528 Intrinsic::ID getIntrinsicID() const {
0529 return getOperand(getNumExplicitDefs()).getIntrinsicID();
0530 }
0531
0532 bool is(Intrinsic::ID ID) const { return getIntrinsicID() == ID; }
0533
0534 bool hasSideEffects() const {
0535 switch (getOpcode()) {
0536 case TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS:
0537 case TargetOpcode::G_INTRINSIC_CONVERGENT_W_SIDE_EFFECTS:
0538 return true;
0539 default:
0540 return false;
0541 }
0542 }
0543
0544 bool isConvergent() const {
0545 switch (getOpcode()) {
0546 case TargetOpcode::G_INTRINSIC_CONVERGENT:
0547 case TargetOpcode::G_INTRINSIC_CONVERGENT_W_SIDE_EFFECTS:
0548 return true;
0549 default:
0550 return false;
0551 }
0552 }
0553
0554 static bool classof(const MachineInstr *MI) {
0555 switch (MI->getOpcode()) {
0556 case TargetOpcode::G_INTRINSIC:
0557 case TargetOpcode::G_INTRINSIC_W_SIDE_EFFECTS:
0558 case TargetOpcode::G_INTRINSIC_CONVERGENT:
0559 case TargetOpcode::G_INTRINSIC_CONVERGENT_W_SIDE_EFFECTS:
0560 return true;
0561 default:
0562 return false;
0563 }
0564 }
0565 };
0566
0567
0568 class GVecReduce : public GenericMachineInstr {
0569 public:
0570 static bool classof(const MachineInstr *MI) {
0571 switch (MI->getOpcode()) {
0572 case TargetOpcode::G_VECREDUCE_FADD:
0573 case TargetOpcode::G_VECREDUCE_FMUL:
0574 case TargetOpcode::G_VECREDUCE_FMAX:
0575 case TargetOpcode::G_VECREDUCE_FMIN:
0576 case TargetOpcode::G_VECREDUCE_FMAXIMUM:
0577 case TargetOpcode::G_VECREDUCE_FMINIMUM:
0578 case TargetOpcode::G_VECREDUCE_ADD:
0579 case TargetOpcode::G_VECREDUCE_MUL:
0580 case TargetOpcode::G_VECREDUCE_AND:
0581 case TargetOpcode::G_VECREDUCE_OR:
0582 case TargetOpcode::G_VECREDUCE_XOR:
0583 case TargetOpcode::G_VECREDUCE_SMAX:
0584 case TargetOpcode::G_VECREDUCE_SMIN:
0585 case TargetOpcode::G_VECREDUCE_UMAX:
0586 case TargetOpcode::G_VECREDUCE_UMIN:
0587 return true;
0588 default:
0589 return false;
0590 }
0591 }
0592
0593
0594
0595 unsigned getScalarOpcForReduction() {
0596 unsigned ScalarOpc;
0597 switch (getOpcode()) {
0598 case TargetOpcode::G_VECREDUCE_FADD:
0599 ScalarOpc = TargetOpcode::G_FADD;
0600 break;
0601 case TargetOpcode::G_VECREDUCE_FMUL:
0602 ScalarOpc = TargetOpcode::G_FMUL;
0603 break;
0604 case TargetOpcode::G_VECREDUCE_FMAX:
0605 ScalarOpc = TargetOpcode::G_FMAXNUM;
0606 break;
0607 case TargetOpcode::G_VECREDUCE_FMIN:
0608 ScalarOpc = TargetOpcode::G_FMINNUM;
0609 break;
0610 case TargetOpcode::G_VECREDUCE_FMAXIMUM:
0611 ScalarOpc = TargetOpcode::G_FMAXIMUM;
0612 break;
0613 case TargetOpcode::G_VECREDUCE_FMINIMUM:
0614 ScalarOpc = TargetOpcode::G_FMINIMUM;
0615 break;
0616 case TargetOpcode::G_VECREDUCE_ADD:
0617 ScalarOpc = TargetOpcode::G_ADD;
0618 break;
0619 case TargetOpcode::G_VECREDUCE_MUL:
0620 ScalarOpc = TargetOpcode::G_MUL;
0621 break;
0622 case TargetOpcode::G_VECREDUCE_AND:
0623 ScalarOpc = TargetOpcode::G_AND;
0624 break;
0625 case TargetOpcode::G_VECREDUCE_OR:
0626 ScalarOpc = TargetOpcode::G_OR;
0627 break;
0628 case TargetOpcode::G_VECREDUCE_XOR:
0629 ScalarOpc = TargetOpcode::G_XOR;
0630 break;
0631 case TargetOpcode::G_VECREDUCE_SMAX:
0632 ScalarOpc = TargetOpcode::G_SMAX;
0633 break;
0634 case TargetOpcode::G_VECREDUCE_SMIN:
0635 ScalarOpc = TargetOpcode::G_SMIN;
0636 break;
0637 case TargetOpcode::G_VECREDUCE_UMAX:
0638 ScalarOpc = TargetOpcode::G_UMAX;
0639 break;
0640 case TargetOpcode::G_VECREDUCE_UMIN:
0641 ScalarOpc = TargetOpcode::G_UMIN;
0642 break;
0643 default:
0644 llvm_unreachable("Unhandled reduction");
0645 }
0646 return ScalarOpc;
0647 }
0648 };
0649
0650
0651 class GPhi : public GenericMachineInstr {
0652 public:
0653
0654 unsigned getNumIncomingValues() const { return (getNumOperands() - 1) / 2; }
0655
0656 Register getIncomingValue(unsigned I) const {
0657 return getOperand(I * 2 + 1).getReg();
0658 }
0659
0660 MachineBasicBlock *getIncomingBlock(unsigned I) const {
0661 return getOperand(I * 2 + 2).getMBB();
0662 }
0663
0664 static bool classof(const MachineInstr *MI) {
0665 return MI->getOpcode() == TargetOpcode::G_PHI;
0666 }
0667 };
0668
0669
0670 class GBinOp : public GenericMachineInstr {
0671 public:
0672 Register getLHSReg() const { return getReg(1); }
0673 Register getRHSReg() const { return getReg(2); }
0674
0675 static bool classof(const MachineInstr *MI) {
0676 switch (MI->getOpcode()) {
0677
0678 case TargetOpcode::G_ADD:
0679 case TargetOpcode::G_SUB:
0680 case TargetOpcode::G_MUL:
0681 case TargetOpcode::G_SDIV:
0682 case TargetOpcode::G_UDIV:
0683 case TargetOpcode::G_SREM:
0684 case TargetOpcode::G_UREM:
0685 case TargetOpcode::G_SMIN:
0686 case TargetOpcode::G_SMAX:
0687 case TargetOpcode::G_UMIN:
0688 case TargetOpcode::G_UMAX:
0689
0690 case TargetOpcode::G_FMINNUM:
0691 case TargetOpcode::G_FMAXNUM:
0692 case TargetOpcode::G_FMINNUM_IEEE:
0693 case TargetOpcode::G_FMAXNUM_IEEE:
0694 case TargetOpcode::G_FMINIMUM:
0695 case TargetOpcode::G_FMAXIMUM:
0696 case TargetOpcode::G_FADD:
0697 case TargetOpcode::G_FSUB:
0698 case TargetOpcode::G_FMUL:
0699 case TargetOpcode::G_FDIV:
0700 case TargetOpcode::G_FPOW:
0701
0702 case TargetOpcode::G_AND:
0703 case TargetOpcode::G_OR:
0704 case TargetOpcode::G_XOR:
0705 return true;
0706 default:
0707 return false;
0708 }
0709 };
0710 };
0711
0712
0713 class GIntBinOp : public GBinOp {
0714 public:
0715 static bool classof(const MachineInstr *MI) {
0716 switch (MI->getOpcode()) {
0717 case TargetOpcode::G_ADD:
0718 case TargetOpcode::G_SUB:
0719 case TargetOpcode::G_MUL:
0720 case TargetOpcode::G_SDIV:
0721 case TargetOpcode::G_UDIV:
0722 case TargetOpcode::G_SREM:
0723 case TargetOpcode::G_UREM:
0724 case TargetOpcode::G_SMIN:
0725 case TargetOpcode::G_SMAX:
0726 case TargetOpcode::G_UMIN:
0727 case TargetOpcode::G_UMAX:
0728 return true;
0729 default:
0730 return false;
0731 }
0732 };
0733 };
0734
0735
0736 class GFBinOp : public GBinOp {
0737 public:
0738 static bool classof(const MachineInstr *MI) {
0739 switch (MI->getOpcode()) {
0740 case TargetOpcode::G_FMINNUM:
0741 case TargetOpcode::G_FMAXNUM:
0742 case TargetOpcode::G_FMINNUM_IEEE:
0743 case TargetOpcode::G_FMAXNUM_IEEE:
0744 case TargetOpcode::G_FMINIMUM:
0745 case TargetOpcode::G_FMAXIMUM:
0746 case TargetOpcode::G_FADD:
0747 case TargetOpcode::G_FSUB:
0748 case TargetOpcode::G_FMUL:
0749 case TargetOpcode::G_FDIV:
0750 case TargetOpcode::G_FPOW:
0751 return true;
0752 default:
0753 return false;
0754 }
0755 };
0756 };
0757
0758
0759 class GLogicalBinOp : public GBinOp {
0760 public:
0761 static bool classof(const MachineInstr *MI) {
0762 switch (MI->getOpcode()) {
0763 case TargetOpcode::G_AND:
0764 case TargetOpcode::G_OR:
0765 case TargetOpcode::G_XOR:
0766 return true;
0767 default:
0768 return false;
0769 }
0770 };
0771 };
0772
0773
0774 class GAdd : public GIntBinOp {
0775 public:
0776 static bool classof(const MachineInstr *MI) {
0777 return MI->getOpcode() == TargetOpcode::G_ADD;
0778 };
0779 };
0780
0781
0782 class GAnd : public GLogicalBinOp {
0783 public:
0784 static bool classof(const MachineInstr *MI) {
0785 return MI->getOpcode() == TargetOpcode::G_AND;
0786 };
0787 };
0788
0789
0790 class GOr : public GLogicalBinOp {
0791 public:
0792 static bool classof(const MachineInstr *MI) {
0793 return MI->getOpcode() == TargetOpcode::G_OR;
0794 };
0795 };
0796
0797
0798 class GExtractVectorElement : public GenericMachineInstr {
0799 public:
0800 Register getVectorReg() const { return getOperand(1).getReg(); }
0801 Register getIndexReg() const { return getOperand(2).getReg(); }
0802
0803 static bool classof(const MachineInstr *MI) {
0804 return MI->getOpcode() == TargetOpcode::G_EXTRACT_VECTOR_ELT;
0805 }
0806 };
0807
0808
0809 class GInsertVectorElement : public GenericMachineInstr {
0810 public:
0811 Register getVectorReg() const { return getOperand(1).getReg(); }
0812 Register getElementReg() const { return getOperand(2).getReg(); }
0813 Register getIndexReg() const { return getOperand(3).getReg(); }
0814
0815 static bool classof(const MachineInstr *MI) {
0816 return MI->getOpcode() == TargetOpcode::G_INSERT_VECTOR_ELT;
0817 }
0818 };
0819
0820
0821 class GExtractSubvector : public GenericMachineInstr {
0822 public:
0823 Register getSrcVec() const { return getOperand(1).getReg(); }
0824 uint64_t getIndexImm() const { return getOperand(2).getImm(); }
0825
0826 static bool classof(const MachineInstr *MI) {
0827 return MI->getOpcode() == TargetOpcode::G_EXTRACT_SUBVECTOR;
0828 }
0829 };
0830
0831
0832 class GInsertSubvector : public GenericMachineInstr {
0833 public:
0834 Register getBigVec() const { return getOperand(1).getReg(); }
0835 Register getSubVec() const { return getOperand(2).getReg(); }
0836 uint64_t getIndexImm() const { return getOperand(3).getImm(); }
0837
0838 static bool classof(const MachineInstr *MI) {
0839 return MI->getOpcode() == TargetOpcode::G_INSERT_SUBVECTOR;
0840 }
0841 };
0842
0843
0844 class GFreeze : public GenericMachineInstr {
0845 public:
0846 Register getSourceReg() const { return getOperand(1).getReg(); }
0847
0848 static bool classof(const MachineInstr *MI) {
0849 return MI->getOpcode() == TargetOpcode::G_FREEZE;
0850 }
0851 };
0852
0853
0854
0855
0856 class GCastOp : public GenericMachineInstr {
0857 public:
0858 Register getSrcReg() const { return getOperand(1).getReg(); }
0859
0860 static bool classof(const MachineInstr *MI) {
0861 switch (MI->getOpcode()) {
0862 case TargetOpcode::G_ADDRSPACE_CAST:
0863 case TargetOpcode::G_FPEXT:
0864 case TargetOpcode::G_FPTOSI:
0865 case TargetOpcode::G_FPTOUI:
0866 case TargetOpcode::G_FPTOSI_SAT:
0867 case TargetOpcode::G_FPTOUI_SAT:
0868 case TargetOpcode::G_FPTRUNC:
0869 case TargetOpcode::G_INTTOPTR:
0870 case TargetOpcode::G_PTRTOINT:
0871 case TargetOpcode::G_SEXT:
0872 case TargetOpcode::G_SITOFP:
0873 case TargetOpcode::G_TRUNC:
0874 case TargetOpcode::G_UITOFP:
0875 case TargetOpcode::G_ZEXT:
0876 case TargetOpcode::G_ANYEXT:
0877 return true;
0878 default:
0879 return false;
0880 }
0881 };
0882 };
0883
0884
0885 class GSext : public GCastOp {
0886 public:
0887 static bool classof(const MachineInstr *MI) {
0888 return MI->getOpcode() == TargetOpcode::G_SEXT;
0889 };
0890 };
0891
0892
0893 class GZext : public GCastOp {
0894 public:
0895 static bool classof(const MachineInstr *MI) {
0896 return MI->getOpcode() == TargetOpcode::G_ZEXT;
0897 };
0898 };
0899
0900
0901 class GAnyExt : public GCastOp {
0902 public:
0903 static bool classof(const MachineInstr *MI) {
0904 return MI->getOpcode() == TargetOpcode::G_ANYEXT;
0905 };
0906 };
0907
0908
0909 class GTrunc : public GCastOp {
0910 public:
0911 static bool classof(const MachineInstr *MI) {
0912 return MI->getOpcode() == TargetOpcode::G_TRUNC;
0913 };
0914 };
0915
0916
0917 class GVScale : public GenericMachineInstr {
0918 public:
0919 APInt getSrc() const { return getOperand(1).getCImm()->getValue(); }
0920
0921 static bool classof(const MachineInstr *MI) {
0922 return MI->getOpcode() == TargetOpcode::G_VSCALE;
0923 };
0924 };
0925
0926
0927 class GStepVector : public GenericMachineInstr {
0928 public:
0929 uint64_t getStep() const {
0930 return getOperand(1).getCImm()->getValue().getZExtValue();
0931 }
0932
0933 static bool classof(const MachineInstr *MI) {
0934 return MI->getOpcode() == TargetOpcode::G_STEP_VECTOR;
0935 };
0936 };
0937
0938
0939 class GSub : public GIntBinOp {
0940 public:
0941 static bool classof(const MachineInstr *MI) {
0942 return MI->getOpcode() == TargetOpcode::G_SUB;
0943 };
0944 };
0945
0946
0947 class GMul : public GIntBinOp {
0948 public:
0949 static bool classof(const MachineInstr *MI) {
0950 return MI->getOpcode() == TargetOpcode::G_MUL;
0951 };
0952 };
0953
0954
0955 class GShl : public GenericMachineInstr {
0956 public:
0957 Register getSrcReg() const { return getOperand(1).getReg(); }
0958 Register getShiftReg() const { return getOperand(2).getReg(); }
0959
0960 static bool classof(const MachineInstr *MI) {
0961 return MI->getOpcode() == TargetOpcode::G_SHL;
0962 };
0963 };
0964
0965
0966 class GSUCmp : public GenericMachineInstr {
0967 public:
0968 Register getLHSReg() const { return getOperand(1).getReg(); }
0969 Register getRHSReg() const { return getOperand(2).getReg(); }
0970
0971 bool isSigned() const { return getOpcode() == TargetOpcode::G_SCMP; }
0972
0973 static bool classof(const MachineInstr *MI) {
0974 switch (MI->getOpcode()) {
0975 case TargetOpcode::G_SCMP:
0976 case TargetOpcode::G_UCMP:
0977 return true;
0978 default:
0979 return false;
0980 }
0981 };
0982 };
0983
0984
0985 class GExtOp : public GCastOp {
0986 public:
0987 static bool classof(const MachineInstr *MI) {
0988 switch (MI->getOpcode()) {
0989 case TargetOpcode::G_SEXT:
0990 case TargetOpcode::G_ZEXT:
0991 case TargetOpcode::G_ANYEXT:
0992 return true;
0993 default:
0994 return false;
0995 }
0996 };
0997 };
0998
0999
1000 class GExtOrTruncOp : public GCastOp {
1001 public:
1002 static bool classof(const MachineInstr *MI) {
1003 switch (MI->getOpcode()) {
1004 case TargetOpcode::G_SEXT:
1005 case TargetOpcode::G_ZEXT:
1006 case TargetOpcode::G_ANYEXT:
1007 case TargetOpcode::G_TRUNC:
1008 return true;
1009 default:
1010 return false;
1011 }
1012 };
1013 };
1014
1015
1016 class GSplatVector : public GenericMachineInstr {
1017 public:
1018 Register getScalarReg() const { return getOperand(1).getReg(); }
1019
1020 static bool classof(const MachineInstr *MI) {
1021 return MI->getOpcode() == TargetOpcode::G_SPLAT_VECTOR;
1022 };
1023 };
1024
1025 }
1026
1027 #endif