Back to home page

EIC code displayed by LXR

 
 

    


Warning, /include/llvm/Target/GenericOpcodes.td is written in an unsupported language. File is not indexed.

0001 //===-- GenericOpcodes.td - Opcodes used with GlobalISel ---*- tablegen -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // This file defines the generic opcodes used with GlobalISel.
0010 // After instruction selection, these opcodes should not appear.
0011 //
0012 //===----------------------------------------------------------------------===//
0013 
0014 //------------------------------------------------------------------------------
0015 // Unary ops.
0016 //------------------------------------------------------------------------------
0017 
0018 class GenericInstruction : StandardPseudoInstruction {
0019   let isPreISelOpcode = true;
0020 
0021   // When all variadic ops share a type with another operand,
0022   // this is the type they share. Used by MIR patterns type inference.
0023   TypedOperand variadicOpsType = ?;
0024 }
0025 
0026 // Provide a variant of an instruction with the same operands, but
0027 // different instruction flags. This is intended to provide a
0028 // convenient way to define strict floating point variants of ordinary
0029 // floating point instructions.
0030 class ConstrainedInstruction<GenericInstruction baseInst> :
0031   GenericInstruction {
0032   let OutOperandList = baseInst.OutOperandList;
0033   let InOperandList =  baseInst.InOperandList;
0034   let isCommutable = baseInst.isCommutable;
0035 
0036   // TODO: Do we need a better way to mark reads from FP mode than
0037   // hasSideEffects?
0038   let hasSideEffects = true;
0039   let mayRaiseFPException = true;
0040 }
0041 
0042 // Extend the underlying scalar type of an operation, leaving the high bits
0043 // unspecified.
0044 def G_ANYEXT : GenericInstruction {
0045   let OutOperandList = (outs type0:$dst);
0046   let InOperandList = (ins type1:$src);
0047   let hasSideEffects = false;
0048 }
0049 
0050 // Sign extend the underlying scalar type of an operation, copying the sign bit
0051 // into the newly-created space.
0052 def G_SEXT : GenericInstruction {
0053   let OutOperandList = (outs type0:$dst);
0054   let InOperandList = (ins type1:$src);
0055   let hasSideEffects = false;
0056 }
0057 
0058 // Sign extend the a value from an arbitrary bit position, copying the sign bit
0059 // into all bits above it. This is equivalent to a shl + ashr pair with an
0060 // appropriate shift amount. $sz is an immediate (MachineOperand::isImm()
0061 // returns true) to allow targets to have some bitwidths legal and others
0062 // lowered. This opcode is particularly useful if the target has sign-extension
0063 // instructions that are cheaper than the constituent shifts as the optimizer is
0064 // able to make decisions on whether it's better to hang on to the G_SEXT_INREG
0065 // or to lower it and optimize the individual shifts.
0066 def G_SEXT_INREG : GenericInstruction {
0067   let OutOperandList = (outs type0:$dst);
0068   let InOperandList = (ins type0:$src, untyped_imm_0:$sz);
0069   let hasSideEffects = false;
0070 }
0071 
0072 // Zero extend the underlying scalar type of an operation, putting zero bits
0073 // into the newly-created space.
0074 def G_ZEXT : GenericInstruction {
0075   let OutOperandList = (outs type0:$dst);
0076   let InOperandList = (ins type1:$src);
0077   let hasSideEffects = false;
0078 }
0079 
0080 
0081 // Truncate the underlying scalar type of an operation. This is equivalent to
0082 // G_EXTRACT for scalar types, but acts elementwise on vectors.
0083 def G_TRUNC : GenericInstruction {
0084   let OutOperandList = (outs type0:$dst);
0085   let InOperandList = (ins type1:$src);
0086   let hasSideEffects = false;
0087 }
0088 
0089 def G_IMPLICIT_DEF : GenericInstruction {
0090   let OutOperandList = (outs type0:$dst);
0091   let InOperandList = (ins);
0092   let hasSideEffects = false;
0093 }
0094 
0095 def G_PHI : GenericInstruction {
0096   let OutOperandList = (outs type0:$dst);
0097   let InOperandList = (ins variable_ops);
0098   let hasSideEffects = false;
0099 }
0100 
0101 def G_FRAME_INDEX : GenericInstruction {
0102   let OutOperandList = (outs ptype0:$dst);
0103   let InOperandList = (ins unknown:$src2);
0104   let hasSideEffects = false;
0105 }
0106 
0107 def G_GLOBAL_VALUE : GenericInstruction {
0108   let OutOperandList = (outs type0:$dst);
0109   let InOperandList = (ins unknown:$src);
0110   let hasSideEffects = false;
0111 }
0112 
0113 def G_PTRAUTH_GLOBAL_VALUE : GenericInstruction {
0114   let OutOperandList = (outs type0:$dst);
0115   let InOperandList = (ins unknown:$addr, i32imm:$key, type1:$addrdisc, i64imm:$disc);
0116   let hasSideEffects = 0;
0117 }
0118 
0119 def G_CONSTANT_POOL : GenericInstruction {
0120   let OutOperandList = (outs type0:$dst);
0121   let InOperandList = (ins unknown:$src);
0122   let hasSideEffects = false;
0123 }
0124 
0125 def G_INTTOPTR : GenericInstruction {
0126   let OutOperandList = (outs type0:$dst);
0127   let InOperandList = (ins type1:$src);
0128   let hasSideEffects = false;
0129 }
0130 
0131 def G_PTRTOINT : GenericInstruction {
0132   let OutOperandList = (outs type0:$dst);
0133   let InOperandList = (ins type1:$src);
0134   let hasSideEffects = false;
0135 }
0136 
0137 def G_BITCAST : GenericInstruction {
0138   let OutOperandList = (outs type0:$dst);
0139   let InOperandList = (ins type1:$src);
0140   let hasSideEffects = false;
0141 }
0142 
0143 // Only supports scalar result types
0144 def G_CONSTANT : GenericInstruction {
0145   let OutOperandList = (outs type0:$dst);
0146   let InOperandList = (ins unknown:$imm);
0147   let hasSideEffects = false;
0148 }
0149 
0150 // Only supports scalar result types
0151 def G_FCONSTANT : GenericInstruction {
0152   let OutOperandList = (outs type0:$dst);
0153   let InOperandList = (ins unknown:$imm);
0154   let hasSideEffects = false;
0155 }
0156 
0157 def G_VASTART : GenericInstruction {
0158   let OutOperandList = (outs);
0159   let InOperandList = (ins type0:$list);
0160   let hasSideEffects = false;
0161   let mayStore = true;
0162 }
0163 
0164 def G_VAARG : GenericInstruction {
0165   let OutOperandList = (outs type0:$val);
0166   let InOperandList = (ins type1:$list, unknown:$align);
0167   let hasSideEffects = false;
0168   let mayLoad = true;
0169   let mayStore = true;
0170 }
0171 
0172 def G_CTLZ : GenericInstruction {
0173   let OutOperandList = (outs type0:$dst);
0174   let InOperandList = (ins type1:$src);
0175   let hasSideEffects = false;
0176 }
0177 
0178 def G_CTLZ_ZERO_UNDEF : GenericInstruction {
0179   let OutOperandList = (outs type0:$dst);
0180   let InOperandList = (ins type1:$src);
0181   let hasSideEffects = false;
0182 }
0183 
0184 def G_CTTZ : GenericInstruction {
0185   let OutOperandList = (outs type0:$dst);
0186   let InOperandList = (ins type1:$src);
0187   let hasSideEffects = false;
0188 }
0189 
0190 def G_CTTZ_ZERO_UNDEF : GenericInstruction {
0191   let OutOperandList = (outs type0:$dst);
0192   let InOperandList = (ins type1:$src);
0193   let hasSideEffects = false;
0194 }
0195 
0196 def G_CTPOP : GenericInstruction {
0197   let OutOperandList = (outs type0:$dst);
0198   let InOperandList = (ins type1:$src);
0199   let hasSideEffects = false;
0200 }
0201 
0202 def G_BSWAP : GenericInstruction {
0203   let OutOperandList = (outs type0:$dst);
0204   let InOperandList = (ins type0:$src);
0205   let hasSideEffects = false;
0206 }
0207 
0208 def G_BITREVERSE : GenericInstruction {
0209   let OutOperandList = (outs type0:$dst);
0210   let InOperandList = (ins type0:$src);
0211   let hasSideEffects = false;
0212 }
0213 
0214 def G_ADDRSPACE_CAST : GenericInstruction {
0215   let OutOperandList = (outs type0:$dst);
0216   let InOperandList = (ins type1:$src);
0217   let hasSideEffects = false;
0218 }
0219 
0220 def G_BLOCK_ADDR : GenericInstruction {
0221   let OutOperandList = (outs type0:$dst);
0222   let InOperandList = (ins unknown:$ba);
0223   let hasSideEffects = false;
0224 }
0225 
0226 def G_JUMP_TABLE : GenericInstruction {
0227   let OutOperandList = (outs type0:$dst);
0228   let InOperandList = (ins unknown:$jti);
0229   let hasSideEffects = false;
0230 }
0231 
0232 def G_DYN_STACKALLOC : GenericInstruction {
0233   let OutOperandList = (outs ptype0:$dst);
0234   let InOperandList = (ins type1:$size, i32imm:$align);
0235   let hasSideEffects = true;
0236 }
0237 
0238 def G_STACKSAVE : GenericInstruction {
0239   let OutOperandList = (outs ptype0:$dst);
0240   let InOperandList = (ins);
0241   let hasSideEffects = true;
0242 }
0243 
0244 def G_STACKRESTORE : GenericInstruction {
0245   let OutOperandList = (outs);
0246   let InOperandList = (ins ptype0:$src);
0247   let hasSideEffects = true;
0248 }
0249 
0250 def G_FREEZE : GenericInstruction {
0251   let OutOperandList = (outs type0:$dst);
0252   let InOperandList = (ins type0:$src);
0253   let hasSideEffects = false;
0254 }
0255 
0256 def G_LROUND: GenericInstruction {
0257   let OutOperandList = (outs type0:$dst);
0258   let InOperandList = (ins type1:$src);
0259   let hasSideEffects = false;
0260 }
0261 
0262 def G_LLROUND: GenericInstruction {
0263   let OutOperandList = (outs type0:$dst);
0264   let InOperandList = (ins type1:$src);
0265   let hasSideEffects = false;
0266 }
0267 
0268 //------------------------------------------------------------------------------
0269 // Binary ops.
0270 //------------------------------------------------------------------------------
0271 
0272 // Generic addition.
0273 def G_ADD : GenericInstruction {
0274   let OutOperandList = (outs type0:$dst);
0275   let InOperandList = (ins type0:$src1, type0:$src2);
0276   let hasSideEffects = false;
0277   let isCommutable = true;
0278 }
0279 
0280 // Generic subtraction.
0281 def G_SUB : GenericInstruction {
0282   let OutOperandList = (outs type0:$dst);
0283   let InOperandList = (ins type0:$src1, type0:$src2);
0284   let hasSideEffects = false;
0285   let isCommutable = false;
0286 }
0287 
0288 // Generic multiplication.
0289 def G_MUL : GenericInstruction {
0290   let OutOperandList = (outs type0:$dst);
0291   let InOperandList = (ins type0:$src1, type0:$src2);
0292   let hasSideEffects = false;
0293   let isCommutable = true;
0294 }
0295 
0296 // Generic signed division.
0297 def G_SDIV : GenericInstruction {
0298   let OutOperandList = (outs type0:$dst);
0299   let InOperandList = (ins type0:$src1, type0:$src2);
0300   let hasSideEffects = false;
0301   let isCommutable = false;
0302 }
0303 
0304 // Generic unsigned division.
0305 def G_UDIV : GenericInstruction {
0306   let OutOperandList = (outs type0:$dst);
0307   let InOperandList = (ins type0:$src1, type0:$src2);
0308   let hasSideEffects = false;
0309   let isCommutable = false;
0310 }
0311 
0312 // Generic signed remainder.
0313 def G_SREM : GenericInstruction {
0314   let OutOperandList = (outs type0:$dst);
0315   let InOperandList = (ins type0:$src1, type0:$src2);
0316   let hasSideEffects = false;
0317   let isCommutable = false;
0318 }
0319 
0320 // Generic unsigned remainder.
0321 def G_UREM : GenericInstruction {
0322   let OutOperandList = (outs type0:$dst);
0323   let InOperandList = (ins type0:$src1, type0:$src2);
0324   let hasSideEffects = false;
0325   let isCommutable = false;
0326 }
0327 
0328 // Generic signed division and remainder.
0329 def G_SDIVREM : GenericInstruction {
0330   let OutOperandList = (outs type0:$div, type0:$rem);
0331   let InOperandList = (ins type0:$src1, type0:$src2);
0332   let hasSideEffects = false;
0333   let isCommutable = false;
0334 }
0335 
0336 // Generic unsigned division and remainder.
0337 def G_UDIVREM : GenericInstruction {
0338   let OutOperandList = (outs type0:$div, type0:$rem);
0339   let InOperandList = (ins type0:$src1, type0:$src2);
0340   let hasSideEffects = false;
0341   let isCommutable = false;
0342 }
0343 
0344 // Generic bitwise and.
0345 def G_AND : GenericInstruction {
0346   let OutOperandList = (outs type0:$dst);
0347   let InOperandList = (ins type0:$src1, type0:$src2);
0348   let hasSideEffects = false;
0349   let isCommutable = true;
0350 }
0351 
0352 // Generic bitwise or.
0353 def G_OR : GenericInstruction {
0354   let OutOperandList = (outs type0:$dst);
0355   let InOperandList = (ins type0:$src1, type0:$src2);
0356   let hasSideEffects = false;
0357   let isCommutable = true;
0358 }
0359 
0360 // Generic bitwise xor.
0361 def G_XOR : GenericInstruction {
0362   let OutOperandList = (outs type0:$dst);
0363   let InOperandList = (ins type0:$src1, type0:$src2);
0364   let hasSideEffects = false;
0365   let isCommutable = true;
0366 }
0367 
0368 // Generic left-shift.
0369 def G_SHL : GenericInstruction {
0370   let OutOperandList = (outs type0:$dst);
0371   let InOperandList = (ins type0:$src1, type1:$src2);
0372   let hasSideEffects = false;
0373 }
0374 
0375 // Generic logical right-shift.
0376 def G_LSHR : GenericInstruction {
0377   let OutOperandList = (outs type0:$dst);
0378   let InOperandList = (ins type0:$src1, type1:$src2);
0379   let hasSideEffects = false;
0380 }
0381 
0382 // Generic arithmetic right-shift.
0383 def G_ASHR : GenericInstruction {
0384   let OutOperandList = (outs type0:$dst);
0385   let InOperandList = (ins type0:$src1, type1:$src2);
0386   let hasSideEffects = false;
0387 }
0388 
0389 // Generic absolute difference signed.
0390 def G_ABDS : GenericInstruction {
0391   let OutOperandList = (outs type0:$dst);
0392   let InOperandList = (ins type0:$src1, type0:$src2);
0393   let hasSideEffects = false;
0394   let isCommutable = true;
0395 }
0396 
0397 // Generic absolute difference unsigned.
0398 def G_ABDU : GenericInstruction {
0399   let OutOperandList = (outs type0:$dst);
0400   let InOperandList = (ins type0:$src1, type0:$src2);
0401   let hasSideEffects = false;
0402   let isCommutable = true;
0403 }
0404 
0405 /// Funnel 'double' shifts take 3 operands, 2 inputs and the shift amount.
0406 /// fshl(X,Y,Z): (X << (Z % bitwidth)) | (Y >> (bitwidth - (Z % bitwidth)))
0407 def G_FSHL : GenericInstruction {
0408   let OutOperandList = (outs type0:$dst);
0409   let InOperandList = (ins type0:$src1, type0:$src2, type1:$src3);
0410   let hasSideEffects = false;
0411 }
0412 
0413 /// Funnel 'double' shifts take 3 operands, 2 inputs and the shift amount.
0414 /// fshr(X,Y,Z): (X << (bitwidth - (Z % bitwidth))) | (Y >> (Z % bitwidth))
0415 def G_FSHR : GenericInstruction {
0416   let OutOperandList = (outs type0:$dst);
0417   let InOperandList = (ins type0:$src1, type0:$src2, type1:$src3);
0418   let hasSideEffects = false;
0419 }
0420 
0421 /// Rotate bits right.
0422 def G_ROTR : GenericInstruction {
0423   let OutOperandList = (outs type0:$dst);
0424   let InOperandList = (ins type0:$src1, type1:$src2);
0425   let hasSideEffects = false;
0426 }
0427 
0428 /// Rotate bits left.
0429 def G_ROTL : GenericInstruction {
0430   let OutOperandList = (outs type0:$dst);
0431   let InOperandList = (ins type0:$src1, type1:$src2);
0432   let hasSideEffects = false;
0433 }
0434 
0435 // Generic integer comparison.
0436 def G_ICMP : GenericInstruction {
0437   let OutOperandList = (outs type0:$dst);
0438   let InOperandList = (ins unknown:$tst, type1:$src1, type1:$src2);
0439   let hasSideEffects = false;
0440 }
0441 
0442 // Generic floating-point comparison.
0443 def G_FCMP : GenericInstruction {
0444   let OutOperandList = (outs type0:$dst);
0445   let InOperandList = (ins unknown:$tst, type1:$src1, type1:$src2);
0446   let hasSideEffects = false;
0447 }
0448 
0449 // Generic signed three-way comparison.
0450 def G_SCMP : GenericInstruction {
0451   let OutOperandList = (outs type0:$dst);
0452   let InOperandList = (ins type1:$src1, type1:$src2);
0453   let hasSideEffects = false;
0454 }
0455 
0456 // Generic unsigned three-way comparison.
0457 def G_UCMP : GenericInstruction {
0458   let OutOperandList = (outs type0:$dst);
0459   let InOperandList = (ins type1:$src1, type1:$src2);
0460   let hasSideEffects = false;
0461 }
0462 
0463 // Generic select
0464 def G_SELECT : GenericInstruction {
0465   let OutOperandList = (outs type0:$dst);
0466   let InOperandList = (ins type1:$tst, type0:$src1, type0:$src2);
0467   let hasSideEffects = false;
0468 }
0469 
0470 // Generic pointer offset.
0471 def G_PTR_ADD : GenericInstruction {
0472   let OutOperandList = (outs ptype0:$dst);
0473   let InOperandList = (ins ptype0:$src1, type1:$src2);
0474   let hasSideEffects = false;
0475 }
0476 
0477 // Generic pointer mask. type1 should be an integer with the same
0478 // bitwidth as the pointer type.
0479 def G_PTRMASK : GenericInstruction {
0480   let OutOperandList = (outs ptype0:$dst);
0481   let InOperandList = (ins ptype0:$src, type1:$bits);
0482   let hasSideEffects = false;
0483 }
0484 
0485 // Generic signed integer minimum.
0486 def G_SMIN : GenericInstruction {
0487   let OutOperandList = (outs type0:$dst);
0488   let InOperandList = (ins type0:$src1, type0:$src2);
0489   let hasSideEffects = false;
0490   let isCommutable = true;
0491 }
0492 
0493 // Generic signed integer maximum.
0494 def G_SMAX : GenericInstruction {
0495   let OutOperandList = (outs type0:$dst);
0496   let InOperandList = (ins type0:$src1, type0:$src2);
0497   let hasSideEffects = false;
0498   let isCommutable = true;
0499 }
0500 
0501 // Generic unsigned integer minimum.
0502 def G_UMIN : GenericInstruction {
0503   let OutOperandList = (outs type0:$dst);
0504   let InOperandList = (ins type0:$src1, type0:$src2);
0505   let hasSideEffects = false;
0506   let isCommutable = true;
0507 }
0508 
0509 // Generic unsigned integer maximum.
0510 def G_UMAX : GenericInstruction {
0511   let OutOperandList = (outs type0:$dst);
0512   let InOperandList = (ins type0:$src1, type0:$src2);
0513   let hasSideEffects = false;
0514   let isCommutable = true;
0515 }
0516 
0517 // Generic integer absolute value.
0518 def G_ABS : GenericInstruction {
0519   let OutOperandList = (outs type0:$dst);
0520   let InOperandList = (ins type0:$src);
0521   let hasSideEffects = false;
0522 }
0523 
0524 //------------------------------------------------------------------------------
0525 // Overflow ops
0526 //------------------------------------------------------------------------------
0527 
0528 // Generic unsigned addition producing a carry flag.
0529 def G_UADDO : GenericInstruction {
0530   let OutOperandList = (outs type0:$dst, type1:$carry_out);
0531   let InOperandList = (ins type0:$src1, type0:$src2);
0532   let hasSideEffects = false;
0533   let isCommutable = true;
0534 }
0535 
0536 // Generic unsigned addition consuming and producing a carry flag.
0537 def G_UADDE : GenericInstruction {
0538   let OutOperandList = (outs type0:$dst, type1:$carry_out);
0539   let InOperandList = (ins type0:$src1, type0:$src2, type1:$carry_in);
0540   let hasSideEffects = false;
0541 }
0542 
0543 // Generic signed addition producing a carry flag.
0544 def G_SADDO : GenericInstruction {
0545   let OutOperandList = (outs type0:$dst, type1:$carry_out);
0546   let InOperandList = (ins type0:$src1, type0:$src2);
0547   let hasSideEffects = false;
0548   let isCommutable = true;
0549 }
0550 
0551 // Generic signed addition consuming and producing a carry flag.
0552 def G_SADDE : GenericInstruction {
0553   let OutOperandList = (outs type0:$dst, type1:$carry_out);
0554   let InOperandList = (ins type0:$src1, type0:$src2, type1:$carry_in);
0555   let hasSideEffects = false;
0556 }
0557 
0558 // Generic unsigned subtraction producing a carry flag.
0559 def G_USUBO : GenericInstruction {
0560   let OutOperandList = (outs type0:$dst, type1:$carry_out);
0561   let InOperandList = (ins type0:$src1, type0:$src2);
0562   let hasSideEffects = false;
0563 }
0564 // Generic unsigned subtraction consuming and producing a carry flag.
0565 def G_USUBE : GenericInstruction {
0566   let OutOperandList = (outs type0:$dst, type1:$carry_out);
0567   let InOperandList = (ins type0:$src1, type0:$src2, type1:$carry_in);
0568   let hasSideEffects = false;
0569 }
0570 
0571 // Generic signed subtraction producing a carry flag.
0572 def G_SSUBO : GenericInstruction {
0573   let OutOperandList = (outs type0:$dst, type1:$carry_out);
0574   let InOperandList = (ins type0:$src1, type0:$src2);
0575   let hasSideEffects = false;
0576 }
0577 
0578 // Generic signed subtraction consuming and producing a carry flag.
0579 def G_SSUBE : GenericInstruction {
0580   let OutOperandList = (outs type0:$dst, type1:$carry_out);
0581   let InOperandList = (ins type0:$src1, type0:$src2, type1:$carry_in);
0582   let hasSideEffects = false;
0583 }
0584 
0585 // Generic unsigned multiplication producing a carry flag.
0586 def G_UMULO : GenericInstruction {
0587   let OutOperandList = (outs type0:$dst, type1:$carry_out);
0588   let InOperandList = (ins type0:$src1, type0:$src2);
0589   let hasSideEffects = false;
0590   let isCommutable = true;
0591 }
0592 
0593 // Generic signed multiplication producing a carry flag.
0594 def G_SMULO : GenericInstruction {
0595   let OutOperandList = (outs type0:$dst, type1:$carry_out);
0596   let InOperandList = (ins type0:$src1, type0:$src2);
0597   let hasSideEffects = false;
0598   let isCommutable = true;
0599 }
0600 
0601 // Multiply two numbers at twice the incoming bit width (unsigned) and return
0602 // the high half of the result.
0603 def G_UMULH : GenericInstruction {
0604   let OutOperandList = (outs type0:$dst);
0605   let InOperandList = (ins type0:$src1, type0:$src2);
0606   let hasSideEffects = false;
0607   let isCommutable = true;
0608 }
0609 
0610 // Multiply two numbers at twice the incoming bit width (signed) and return
0611 // the high half of the result.
0612 def G_SMULH : GenericInstruction {
0613   let OutOperandList = (outs type0:$dst);
0614   let InOperandList = (ins type0:$src1, type0:$src2);
0615   let hasSideEffects = false;
0616   let isCommutable = true;
0617 }
0618 
0619 //------------------------------------------------------------------------------
0620 // Saturating ops
0621 //------------------------------------------------------------------------------
0622 
0623 // Generic saturating unsigned addition.
0624 def G_UADDSAT : GenericInstruction {
0625   let OutOperandList = (outs type0:$dst);
0626   let InOperandList = (ins type0:$src1, type0:$src2);
0627   let hasSideEffects = false;
0628   let isCommutable = true;
0629 }
0630 
0631 // Generic saturating signed addition.
0632 def G_SADDSAT : GenericInstruction {
0633   let OutOperandList = (outs type0:$dst);
0634   let InOperandList = (ins type0:$src1, type0:$src2);
0635   let hasSideEffects = false;
0636   let isCommutable = true;
0637 }
0638 
0639 // Generic saturating unsigned subtraction.
0640 def G_USUBSAT : GenericInstruction {
0641   let OutOperandList = (outs type0:$dst);
0642   let InOperandList = (ins type0:$src1, type0:$src2);
0643   let hasSideEffects = false;
0644   let isCommutable = false;
0645 }
0646 
0647 // Generic saturating signed subtraction.
0648 def G_SSUBSAT : GenericInstruction {
0649   let OutOperandList = (outs type0:$dst);
0650   let InOperandList = (ins type0:$src1, type0:$src2);
0651   let hasSideEffects = false;
0652   let isCommutable = false;
0653 }
0654 
0655 // Generic saturating unsigned left shift.
0656 def G_USHLSAT : GenericInstruction {
0657   let OutOperandList = (outs type0:$dst);
0658   let InOperandList = (ins type0:$src1, type1:$src2);
0659   let hasSideEffects = false;
0660   let isCommutable = false;
0661 }
0662 
0663 // Generic saturating signed left shift.
0664 def G_SSHLSAT : GenericInstruction {
0665   let OutOperandList = (outs type0:$dst);
0666   let InOperandList = (ins type0:$src1, type1:$src2);
0667   let hasSideEffects = false;
0668   let isCommutable = false;
0669 }
0670 
0671 /// RESULT = [US]MULFIX(LHS, RHS, SCALE) - Perform fixed point
0672 /// multiplication on 2 integers with the same width and scale. SCALE
0673 /// represents the scale of both operands as fixed point numbers. This
0674 /// SCALE parameter must be a constant integer. A scale of zero is
0675 /// effectively performing multiplication on 2 integers.
0676 def G_SMULFIX : GenericInstruction {
0677   let OutOperandList = (outs type0:$dst);
0678   let InOperandList = (ins type0:$src0, type0:$src1, untyped_imm_0:$scale);
0679   let hasSideEffects = false;
0680   let isCommutable = true;
0681 }
0682 
0683 def G_UMULFIX : GenericInstruction {
0684   let OutOperandList = (outs type0:$dst);
0685   let InOperandList = (ins type0:$src0, type0:$src1, untyped_imm_0:$scale);
0686   let hasSideEffects = false;
0687   let isCommutable = true;
0688 }
0689 
0690 /// Same as the corresponding unsaturated fixed point instructions, but the
0691 /// result is clamped between the min and max values representable by the
0692 /// bits of the first 2 operands.
0693 def G_SMULFIXSAT : GenericInstruction {
0694   let OutOperandList = (outs type0:$dst);
0695   let InOperandList = (ins type0:$src0, type0:$src1, untyped_imm_0:$scale);
0696   let hasSideEffects = false;
0697   let isCommutable = true;
0698 }
0699 
0700 def G_UMULFIXSAT : GenericInstruction {
0701   let OutOperandList = (outs type0:$dst);
0702   let InOperandList = (ins type0:$src0, type0:$src1, untyped_imm_0:$scale);
0703   let hasSideEffects = false;
0704   let isCommutable = true;
0705 }
0706 
0707 /// RESULT = [US]DIVFIX(LHS, RHS, SCALE) - Perform fixed point division on
0708 /// 2 integers with the same width and scale. SCALE represents the scale
0709 /// of both operands as fixed point numbers. This SCALE parameter must be a
0710 /// constant integer.
0711 def G_SDIVFIX : GenericInstruction {
0712   let OutOperandList = (outs type0:$dst);
0713   let InOperandList = (ins type0:$src0, type0:$src1, untyped_imm_0:$scale);
0714   let hasSideEffects = false;
0715   let isCommutable = false;
0716 }
0717 
0718 def G_UDIVFIX : GenericInstruction {
0719   let OutOperandList = (outs type0:$dst);
0720   let InOperandList = (ins type0:$src0, type0:$src1, untyped_imm_0:$scale);
0721   let hasSideEffects = false;
0722   let isCommutable = false;
0723 }
0724 
0725 /// Same as the corresponding unsaturated fixed point instructions,
0726 /// but the result is clamped between the min and max values
0727 /// representable by the bits of the first 2 operands.
0728 def G_SDIVFIXSAT : GenericInstruction {
0729   let OutOperandList = (outs type0:$dst);
0730   let InOperandList = (ins type0:$src0, type0:$src1, untyped_imm_0:$scale);
0731   let hasSideEffects = false;
0732   let isCommutable = false;
0733 }
0734 
0735 def G_UDIVFIXSAT : GenericInstruction {
0736   let OutOperandList = (outs type0:$dst);
0737   let InOperandList = (ins type0:$src0, type0:$src1, untyped_imm_0:$scale);
0738   let hasSideEffects = false;
0739   let isCommutable = false;
0740 }
0741 
0742 //------------------------------------------------------------------------------
0743 // Floating Point Unary Ops.
0744 //------------------------------------------------------------------------------
0745 
0746 def G_FNEG : GenericInstruction {
0747   let OutOperandList = (outs type0:$dst);
0748   let InOperandList = (ins type0:$src);
0749   let hasSideEffects = false;
0750 }
0751 
0752 def G_FPEXT : GenericInstruction {
0753   let OutOperandList = (outs type0:$dst);
0754   let InOperandList = (ins type1:$src);
0755   let hasSideEffects = false;
0756 }
0757 
0758 def G_FPTRUNC : GenericInstruction {
0759   let OutOperandList = (outs type0:$dst);
0760   let InOperandList = (ins type1:$src);
0761   let hasSideEffects = false;
0762 }
0763 
0764 def G_FPTOSI : GenericInstruction {
0765   let OutOperandList = (outs type0:$dst);
0766   let InOperandList = (ins type1:$src);
0767   let hasSideEffects = false;
0768 }
0769 
0770 def G_FPTOUI : GenericInstruction {
0771   let OutOperandList = (outs type0:$dst);
0772   let InOperandList = (ins type1:$src);
0773   let hasSideEffects = false;
0774 }
0775 
0776 def G_SITOFP : GenericInstruction {
0777   let OutOperandList = (outs type0:$dst);
0778   let InOperandList = (ins type1:$src);
0779   let hasSideEffects = false;
0780 }
0781 
0782 def G_UITOFP : GenericInstruction {
0783   let OutOperandList = (outs type0:$dst);
0784   let InOperandList = (ins type1:$src);
0785   let hasSideEffects = false;
0786 }
0787 
0788 def G_FPTOSI_SAT : GenericInstruction {
0789   let OutOperandList = (outs type0:$dst);
0790   let InOperandList = (ins type1:$src);
0791   let hasSideEffects = false;
0792 }
0793 
0794 def G_FPTOUI_SAT : GenericInstruction {
0795   let OutOperandList = (outs type0:$dst);
0796   let InOperandList = (ins type1:$src);
0797   let hasSideEffects = false;
0798 }
0799 
0800 def G_FABS : GenericInstruction {
0801   let OutOperandList = (outs type0:$dst);
0802   let InOperandList = (ins type0:$src);
0803   let hasSideEffects = false;
0804 }
0805 
0806 def G_FCOPYSIGN : GenericInstruction {
0807   let OutOperandList = (outs type0:$dst);
0808   let InOperandList = (ins type0:$src0, type1:$src1);
0809   let hasSideEffects = false;
0810 }
0811 
0812 def G_FCANONICALIZE : GenericInstruction {
0813   let OutOperandList = (outs type0:$dst);
0814   let InOperandList = (ins type0:$src);
0815   let hasSideEffects = false;
0816 }
0817 
0818 // Generic opcode equivalent to the llvm.is_fpclass intrinsic.
0819 def G_IS_FPCLASS: GenericInstruction {
0820   let OutOperandList = (outs type0:$dst);
0821   let InOperandList = (ins type1:$src, unknown:$test);
0822   let hasSideEffects = false;
0823 }
0824 
0825 // FMINNUM/FMAXNUM - Perform floating-point minimum or maximum on two
0826 // values.
0827 //
0828 // In the case where a single input is a NaN (either signaling or quiet),
0829 // the non-NaN input is returned.
0830 //
0831 // The return value of (FMINNUM 0.0, -0.0) could be either 0.0 or -0.0.
0832 def G_FMINNUM : GenericInstruction {
0833   let OutOperandList = (outs type0:$dst);
0834   let InOperandList = (ins type0:$src1, type0:$src2);
0835   let hasSideEffects = false;
0836   let isCommutable = true;
0837 }
0838 
0839 def G_FMAXNUM : GenericInstruction {
0840   let OutOperandList = (outs type0:$dst);
0841   let InOperandList = (ins type0:$src1, type0:$src2);
0842   let hasSideEffects = false;
0843   let isCommutable = true;
0844 }
0845 
0846 // FMINNUM_IEEE/FMAXNUM_IEEE - Perform floating-point minimumNumber or
0847 // maximumNumber on two values, following IEEE-754 definitions. This
0848 // differs from FMINNUM/FMAXNUM in the handling of signaling NaNs, and
0849 // signed zero.
0850 //
0851 // If one input is a signaling NaN, returns a quiet NaN. This matches
0852 // IEEE-754 2008's minnum/maxnum behavior for signaling NaNs (which
0853 // differs from 2019).
0854 //
0855 // These treat -0 as ordered less than +0, matching the behavior of
0856 // IEEE-754 2019's minimumNumber/maximumNumber.
0857 def G_FMINNUM_IEEE : GenericInstruction {
0858   let OutOperandList = (outs type0:$dst);
0859   let InOperandList = (ins type0:$src1, type0:$src2);
0860   let hasSideEffects = false;
0861   let isCommutable = true;
0862 }
0863 
0864 def G_FMAXNUM_IEEE : GenericInstruction {
0865   let OutOperandList = (outs type0:$dst);
0866   let InOperandList = (ins type0:$src1, type0:$src2);
0867   let hasSideEffects = false;
0868   let isCommutable = true;
0869 }
0870 
0871 // FMINIMUM/FMAXIMUM - NaN-propagating minimum/maximum that also treat -0.0
0872 // as less than 0.0. While FMINNUM_IEEE/FMAXNUM_IEEE follow IEEE 754-2008
0873 // semantics, FMINIMUM/FMAXIMUM follow IEEE 754-2019 semantics.
0874 def G_FMINIMUM : GenericInstruction {
0875   let OutOperandList = (outs type0:$dst);
0876   let InOperandList = (ins type0:$src1, type0:$src2);
0877   let hasSideEffects = false;
0878   let isCommutable = true;
0879 }
0880 
0881 def G_FMAXIMUM : GenericInstruction {
0882   let OutOperandList = (outs type0:$dst);
0883   let InOperandList = (ins type0:$src1, type0:$src2);
0884   let hasSideEffects = false;
0885   let isCommutable = true;
0886 }
0887 
0888 //------------------------------------------------------------------------------
0889 // Floating Point Binary ops.
0890 //------------------------------------------------------------------------------
0891 
0892 // Generic FP addition.
0893 def G_FADD : GenericInstruction {
0894   let OutOperandList = (outs type0:$dst);
0895   let InOperandList = (ins type0:$src1, type0:$src2);
0896   let hasSideEffects = false;
0897   let isCommutable = true;
0898 }
0899 
0900 // Generic FP subtraction.
0901 def G_FSUB : GenericInstruction {
0902   let OutOperandList = (outs type0:$dst);
0903   let InOperandList = (ins type0:$src1, type0:$src2);
0904   let hasSideEffects = false;
0905   let isCommutable = false;
0906 }
0907 
0908 // Generic FP multiplication.
0909 def G_FMUL : GenericInstruction {
0910   let OutOperandList = (outs type0:$dst);
0911   let InOperandList = (ins type0:$src1, type0:$src2);
0912   let hasSideEffects = false;
0913   let isCommutable = true;
0914 }
0915 
0916 // Generic fused multiply-add instruction.
0917 // Behaves like llvm fma intrinsic ie src1 * src2 + src3
0918 def G_FMA : GenericInstruction {
0919   let OutOperandList = (outs type0:$dst);
0920   let InOperandList = (ins type0:$src1, type0:$src2, type0:$src3);
0921   let hasSideEffects = false;
0922   let isCommutable = false;
0923 }
0924 
0925 /// Generic FP multiply and add. Perform a * b + c, while getting the
0926 /// same result as the separately rounded operations, unlike G_FMA.
0927 def G_FMAD : GenericInstruction {
0928   let OutOperandList = (outs type0:$dst);
0929   let InOperandList = (ins type0:$src1, type0:$src2, type0:$src3);
0930   let hasSideEffects = false;
0931   let isCommutable = false;
0932 }
0933 
0934 // Generic FP division.
0935 def G_FDIV : GenericInstruction {
0936   let OutOperandList = (outs type0:$dst);
0937   let InOperandList = (ins type0:$src1, type0:$src2);
0938   let hasSideEffects = false;
0939 }
0940 
0941 // Generic FP remainder.
0942 def G_FREM : GenericInstruction {
0943   let OutOperandList = (outs type0:$dst);
0944   let InOperandList = (ins type0:$src1, type0:$src2);
0945   let hasSideEffects = false;
0946 }
0947 
0948 // Floating point exponentiation.
0949 def G_FPOW : GenericInstruction {
0950   let OutOperandList = (outs type0:$dst);
0951   let InOperandList = (ins type0:$src1, type0:$src2);
0952   let hasSideEffects = false;
0953 }
0954 
0955 // Floating point exponentiation, with an integer power.
0956 def G_FPOWI : GenericInstruction {
0957   let OutOperandList = (outs type0:$dst);
0958   let InOperandList = (ins type0:$src0, type1:$src1);
0959   let hasSideEffects = false;
0960 }
0961 
0962 // Floating point base-e exponential of a value.
0963 def G_FEXP : GenericInstruction {
0964   let OutOperandList = (outs type0:$dst);
0965   let InOperandList = (ins type0:$src1);
0966   let hasSideEffects = false;
0967 }
0968 
0969 // Floating point base-2 exponential of a value.
0970 def G_FEXP2 : GenericInstruction {
0971   let OutOperandList = (outs type0:$dst);
0972   let InOperandList = (ins type0:$src1);
0973   let hasSideEffects = false;
0974 }
0975 
0976 // Floating point base-10 exponential of a value.
0977 def G_FEXP10 : GenericInstruction {
0978   let OutOperandList = (outs type0:$dst);
0979   let InOperandList = (ins type0:$src1);
0980   let hasSideEffects = false;
0981 }
0982 
0983 // Floating point base-e logarithm of a value.
0984 def G_FLOG : GenericInstruction {
0985   let OutOperandList = (outs type0:$dst);
0986   let InOperandList = (ins type0:$src1);
0987   let hasSideEffects = false;
0988 }
0989 
0990 // Floating point base-2 logarithm of a value.
0991 def G_FLOG2 : GenericInstruction {
0992   let OutOperandList = (outs type0:$dst);
0993   let InOperandList = (ins type0:$src1);
0994   let hasSideEffects = false;
0995 }
0996 
0997 // Floating point base-10 logarithm of a value.
0998 def G_FLOG10 : GenericInstruction {
0999   let OutOperandList = (outs type0:$dst);
1000   let InOperandList = (ins type0:$src1);
1001   let hasSideEffects = false;
1002 }
1003 
1004 // Floating point x * 2^n
1005 def G_FLDEXP : GenericInstruction {
1006   let OutOperandList = (outs type0:$dst);
1007   let InOperandList = (ins type0:$src0, type1:$src1);
1008   let hasSideEffects = false;
1009 }
1010 
1011 // Floating point frexp
1012 def G_FFREXP : GenericInstruction {
1013   let OutOperandList = (outs type0:$dst0, type1:$dst1);
1014   let InOperandList = (ins type0:$src0);
1015   let hasSideEffects = false;
1016 }
1017 
1018 // Floating point ceiling of a value.
1019 def G_FCEIL : GenericInstruction {
1020   let OutOperandList = (outs type0:$dst);
1021   let InOperandList = (ins type0:$src1);
1022   let hasSideEffects = false;
1023 }
1024 
1025 // Floating point cosine of a value.
1026 def G_FCOS : GenericInstruction {
1027   let OutOperandList = (outs type0:$dst);
1028   let InOperandList = (ins type0:$src1);
1029   let hasSideEffects = false;
1030 }
1031 
1032 // Floating point sine of a value.
1033 def G_FSIN : GenericInstruction {
1034   let OutOperandList = (outs type0:$dst);
1035   let InOperandList = (ins type0:$src1);
1036   let hasSideEffects = false;
1037 }
1038 
1039 // Floating point combined sine and cosine.
1040 def G_FSINCOS : GenericInstruction {
1041   let OutOperandList = (outs type0:$dst1, type0:$dst2);
1042   let InOperandList = (ins type0:$src1);
1043   let hasSideEffects = false;
1044 }
1045 
1046 // Floating point tangent of a value.
1047 def G_FTAN : GenericInstruction {
1048   let OutOperandList = (outs type0:$dst);
1049   let InOperandList = (ins type0:$src1);
1050   let hasSideEffects = false;
1051 }
1052 
1053 // Floating point arccosine of a value.
1054 def G_FACOS : GenericInstruction {
1055   let OutOperandList = (outs type0:$dst);
1056   let InOperandList = (ins type0:$src1);
1057   let hasSideEffects = false;
1058 }
1059 
1060 // Floating point arcsine of a value.
1061 def G_FASIN : GenericInstruction {
1062   let OutOperandList = (outs type0:$dst);
1063   let InOperandList = (ins type0:$src1);
1064   let hasSideEffects = false;
1065 }
1066 
1067 // Floating point arctangent of a value.
1068 def G_FATAN : GenericInstruction {
1069   let OutOperandList = (outs type0:$dst);
1070   let InOperandList = (ins type0:$src1);
1071   let hasSideEffects = false;
1072 }
1073 
1074 // Floating point arctangent of a value.
1075 def G_FATAN2 : GenericInstruction {
1076   let OutOperandList = (outs type0:$dst);
1077   let InOperandList = (ins type0:$src1, type0:$src2);
1078   let hasSideEffects = false;
1079 }
1080 
1081 // Floating point hyperbolic cosine of a value.
1082 def G_FCOSH : GenericInstruction {
1083   let OutOperandList = (outs type0:$dst);
1084   let InOperandList = (ins type0:$src1);
1085   let hasSideEffects = false;
1086 }
1087 
1088 // Floating point hyperbolic sine of a value.
1089 def G_FSINH : GenericInstruction {
1090   let OutOperandList = (outs type0:$dst);
1091   let InOperandList = (ins type0:$src1);
1092   let hasSideEffects = false;
1093 }
1094 
1095 // Floating point hyperbolic tangent of a value.
1096 def G_FTANH : GenericInstruction {
1097   let OutOperandList = (outs type0:$dst);
1098   let InOperandList = (ins type0:$src1);
1099   let hasSideEffects = false;
1100 }
1101 
1102 // Floating point square root of a value.
1103 // This returns NaN for negative nonzero values.
1104 // NOTE: Unlike libm sqrt(), this never sets errno. In all other respects it's
1105 // libm-conformant.
1106 def G_FSQRT : GenericInstruction {
1107   let OutOperandList = (outs type0:$dst);
1108   let InOperandList = (ins type0:$src1);
1109   let hasSideEffects = false;
1110 }
1111 
1112 // Floating point floor of a value.
1113 def G_FFLOOR : GenericInstruction {
1114   let OutOperandList = (outs type0:$dst);
1115   let InOperandList = (ins type0:$src1);
1116   let hasSideEffects = false;
1117 }
1118 
1119 // Floating point round to next integer.
1120 def G_FRINT : GenericInstruction {
1121   let OutOperandList = (outs type0:$dst);
1122   let InOperandList = (ins type0:$src1);
1123   let hasSideEffects = false;
1124 }
1125 
1126 // Floating point round to the nearest integer.
1127 def G_FNEARBYINT : GenericInstruction {
1128   let OutOperandList = (outs type0:$dst);
1129   let InOperandList = (ins type0:$src1);
1130   let hasSideEffects = false;
1131 }
1132 
1133 //------------------------------------------------------------------------------
1134 // Access to floating-point environment.
1135 //------------------------------------------------------------------------------
1136 
1137 // These operations read/write floating-point environment. The interaction with
1138 // it is modeled as a side effect, because constrained intrinsics use the same
1139 // method.
1140 
1141 // Reading floating-point environment.
1142 def G_GET_FPENV : GenericInstruction {
1143   let OutOperandList = (outs type0:$dst);
1144   let InOperandList = (ins);
1145   let hasSideEffects = true;
1146 }
1147 
1148 // Setting floating-point environment.
1149 def G_SET_FPENV : GenericInstruction {
1150   let OutOperandList = (outs);
1151   let InOperandList = (ins type0:$src);
1152   let hasSideEffects = true;
1153 }
1154 
1155 // Setting default floating-point environment.
1156 def G_RESET_FPENV : GenericInstruction {
1157   let OutOperandList = (outs);
1158   let InOperandList = (ins);
1159   let hasSideEffects = true;
1160 }
1161 
1162 // Reading floating-point control modes.
1163 def G_GET_FPMODE : GenericInstruction {
1164   let OutOperandList = (outs type0:$dst);
1165   let InOperandList = (ins);
1166   let hasSideEffects = true;
1167 }
1168 
1169 // Setting floating-point control modes.
1170 def G_SET_FPMODE : GenericInstruction {
1171   let OutOperandList = (outs);
1172   let InOperandList = (ins type0:$src);
1173   let hasSideEffects = true;
1174 }
1175 
1176 // Setting floating-point control modes to default state.
1177 def G_RESET_FPMODE : GenericInstruction {
1178   let OutOperandList = (outs);
1179   let InOperandList = (ins);
1180   let hasSideEffects = true;
1181 }
1182 
1183 //------------------------------------------------------------------------------
1184 // Opcodes for LLVM Intrinsics
1185 //------------------------------------------------------------------------------
1186 def G_INTRINSIC_FPTRUNC_ROUND : GenericInstruction {
1187   let OutOperandList = (outs type0:$dst);
1188   let InOperandList = (ins type1:$src1, i32imm:$round_mode);
1189   let hasSideEffects = false;
1190 }
1191 
1192 def G_INTRINSIC_TRUNC : GenericInstruction {
1193   let OutOperandList = (outs type0:$dst);
1194   let InOperandList = (ins type0:$src1);
1195   let hasSideEffects = false;
1196 }
1197 
1198 def G_INTRINSIC_ROUND : GenericInstruction {
1199   let OutOperandList = (outs type0:$dst);
1200   let InOperandList = (ins type0:$src1);
1201   let hasSideEffects = false;
1202 }
1203 
1204 def G_INTRINSIC_LRINT : GenericInstruction {
1205   let OutOperandList = (outs type0:$dst);
1206   let InOperandList = (ins type1:$src);
1207   let hasSideEffects = false;
1208 }
1209 
1210 def G_INTRINSIC_LLRINT : GenericInstruction {
1211   let OutOperandList = (outs type0:$dst);
1212   let InOperandList = (ins type1:$src);
1213   let hasSideEffects = false;
1214 }
1215 
1216 def G_INTRINSIC_ROUNDEVEN : GenericInstruction {
1217   let OutOperandList = (outs type0:$dst);
1218   let InOperandList = (ins type0:$src1);
1219   let hasSideEffects = false;
1220 }
1221 
1222 def G_READCYCLECOUNTER : GenericInstruction {
1223   let OutOperandList = (outs type0:$dst);
1224   let InOperandList = (ins);
1225   let hasSideEffects = true;
1226 }
1227 
1228 def G_READSTEADYCOUNTER : GenericInstruction {
1229   let OutOperandList = (outs type0:$dst);
1230   let InOperandList = (ins);
1231   let hasSideEffects = true;
1232 }
1233 
1234 //------------------------------------------------------------------------------
1235 // Memory ops
1236 //------------------------------------------------------------------------------
1237 
1238 // Generic load. Expects a MachineMemOperand in addition to explicit
1239 // operands. If the result size is larger than the memory size, the
1240 // high bits are undefined. If the result is a vector type and larger
1241 // than the memory size, the high elements are undefined (i.e. this is
1242 // not a per-element, vector anyextload)
1243 def G_LOAD : GenericInstruction {
1244   let OutOperandList = (outs type0:$dst);
1245   let InOperandList = (ins ptype1:$addr);
1246   let hasSideEffects = false;
1247   let mayLoad = true;
1248 }
1249 
1250 // Generic sign-extended load. Expects a MachineMemOperand in addition to explicit operands.
1251 def G_SEXTLOAD : GenericInstruction {
1252   let OutOperandList = (outs type0:$dst);
1253   let InOperandList = (ins ptype1:$addr);
1254   let hasSideEffects = false;
1255   let mayLoad = true;
1256 }
1257 
1258 // Generic zero-extended load. Expects a MachineMemOperand in addition to explicit operands.
1259 def G_ZEXTLOAD : GenericInstruction {
1260   let OutOperandList = (outs type0:$dst);
1261   let InOperandList = (ins ptype1:$addr);
1262   let hasSideEffects = false;
1263   let mayLoad = true;
1264 }
1265 
1266 // Generic indexed load. Combines a GEP with a load. $newaddr is set to $base + $offset.
1267 // If $am is 0 (post-indexed), then the value is loaded from $base; if $am is 1 (pre-indexed)
1268 //  then the value is loaded from $newaddr.
1269 def G_INDEXED_LOAD : GenericInstruction {
1270   let OutOperandList = (outs type0:$dst, ptype1:$newaddr);
1271   let InOperandList = (ins ptype1:$base, type2:$offset, unknown:$am);
1272   let hasSideEffects = false;
1273   let mayLoad = true;
1274 }
1275 
1276 // Same as G_INDEXED_LOAD except that the load performed is sign-extending, as with G_SEXTLOAD.
1277 def G_INDEXED_SEXTLOAD : GenericInstruction {
1278   let OutOperandList = (outs type0:$dst, ptype1:$newaddr);
1279   let InOperandList = (ins ptype1:$base, type2:$offset, unknown:$am);
1280   let hasSideEffects = false;
1281   let mayLoad = true;
1282 }
1283 
1284 // Same as G_INDEXED_LOAD except that the load performed is zero-extending, as with G_ZEXTLOAD.
1285 def G_INDEXED_ZEXTLOAD : GenericInstruction {
1286   let OutOperandList = (outs type0:$dst, ptype1:$newaddr);
1287   let InOperandList = (ins ptype1:$base, type2:$offset, unknown:$am);
1288   let hasSideEffects = false;
1289   let mayLoad = true;
1290 }
1291 
1292 // Generic store. Expects a MachineMemOperand in addition to explicit operands.
1293 def G_STORE : GenericInstruction {
1294   let OutOperandList = (outs);
1295   let InOperandList = (ins type0:$src, ptype1:$addr);
1296   let hasSideEffects = false;
1297   let mayStore = true;
1298 }
1299 
1300 // Combines a store with a GEP. See description of G_INDEXED_LOAD for indexing behaviour.
1301 def G_INDEXED_STORE : GenericInstruction {
1302   let OutOperandList = (outs ptype0:$newaddr);
1303   let InOperandList = (ins type1:$src, ptype0:$base, ptype2:$offset,
1304                            unknown:$am);
1305   let hasSideEffects = false;
1306   let mayStore = true;
1307 }
1308 
1309 // Generic atomic cmpxchg with internal success check. Expects a
1310 // MachineMemOperand in addition to explicit operands.
1311 def G_ATOMIC_CMPXCHG_WITH_SUCCESS : GenericInstruction {
1312   let OutOperandList = (outs type0:$oldval, type1:$success);
1313   let InOperandList = (ins type2:$addr, type0:$cmpval, type0:$newval);
1314   let hasSideEffects = false;
1315   let mayLoad = true;
1316   let mayStore = true;
1317 }
1318 
1319 // Generic atomic cmpxchg. Expects a MachineMemOperand in addition to explicit
1320 // operands.
1321 def G_ATOMIC_CMPXCHG : GenericInstruction {
1322   let OutOperandList = (outs type0:$oldval);
1323   let InOperandList = (ins ptype1:$addr, type0:$cmpval, type0:$newval);
1324   let hasSideEffects = false;
1325   let mayLoad = true;
1326   let mayStore = true;
1327 }
1328 
1329 // Generic atomicrmw. Expects a MachineMemOperand in addition to explicit
1330 // operands.
1331 class G_ATOMICRMW_OP : GenericInstruction {
1332   let OutOperandList = (outs type0:$oldval);
1333   let InOperandList = (ins ptype1:$addr, type0:$val);
1334   let hasSideEffects = false;
1335   let mayLoad = true;
1336   let mayStore = true;
1337 }
1338 
1339 def G_ATOMICRMW_XCHG : G_ATOMICRMW_OP;
1340 def G_ATOMICRMW_ADD : G_ATOMICRMW_OP;
1341 def G_ATOMICRMW_SUB : G_ATOMICRMW_OP;
1342 def G_ATOMICRMW_AND : G_ATOMICRMW_OP;
1343 def G_ATOMICRMW_NAND : G_ATOMICRMW_OP;
1344 def G_ATOMICRMW_OR : G_ATOMICRMW_OP;
1345 def G_ATOMICRMW_XOR : G_ATOMICRMW_OP;
1346 def G_ATOMICRMW_MAX : G_ATOMICRMW_OP;
1347 def G_ATOMICRMW_MIN : G_ATOMICRMW_OP;
1348 def G_ATOMICRMW_UMAX : G_ATOMICRMW_OP;
1349 def G_ATOMICRMW_UMIN : G_ATOMICRMW_OP;
1350 def G_ATOMICRMW_FADD : G_ATOMICRMW_OP;
1351 def G_ATOMICRMW_FSUB : G_ATOMICRMW_OP;
1352 def G_ATOMICRMW_FMAX : G_ATOMICRMW_OP;
1353 def G_ATOMICRMW_FMIN : G_ATOMICRMW_OP;
1354 def G_ATOMICRMW_UINC_WRAP : G_ATOMICRMW_OP;
1355 def G_ATOMICRMW_UDEC_WRAP : G_ATOMICRMW_OP;
1356 def G_ATOMICRMW_USUB_COND : G_ATOMICRMW_OP;
1357 def G_ATOMICRMW_USUB_SAT : G_ATOMICRMW_OP;
1358 
1359 def G_FENCE : GenericInstruction {
1360   let OutOperandList = (outs);
1361   let InOperandList = (ins i32imm:$ordering, i32imm:$scope);
1362   let hasSideEffects = true;
1363 }
1364 
1365 // Generic opcode equivalent to the llvm.prefetch intrinsic.
1366 def G_PREFETCH : GenericInstruction {
1367   let OutOperandList = (outs);
1368   let InOperandList = (ins ptype0:$address, i32imm:$rw, i32imm:$locality, i32imm:$cachetype);
1369   let hasSideEffects = true;
1370   let mayLoad = true;
1371   let mayStore = true;
1372 }
1373 
1374 //------------------------------------------------------------------------------
1375 // Variadic ops
1376 //------------------------------------------------------------------------------
1377 
1378 // Extract a register of the specified size, starting from the block given by
1379 // index. This will almost certainly be mapped to sub-register COPYs after
1380 // register banks have been selected.
1381 def G_EXTRACT : GenericInstruction {
1382   let OutOperandList = (outs type0:$res);
1383   let InOperandList = (ins type1:$src, untyped_imm_0:$offset);
1384   let hasSideEffects = false;
1385 }
1386 
1387 // Extract multiple registers specified size, starting from blocks given by
1388 // indexes. This will almost certainly be mapped to sub-register COPYs after
1389 // register banks have been selected.
1390 // The output operands are always ordered from lowest bits to highest:
1391 //   %bits_0_7:(s8), %bits_8_15:(s8),
1392 //       %bits_16_23:(s8), %bits_24_31:(s8) = G_UNMERGE_VALUES %0:(s32)
1393 def G_UNMERGE_VALUES : GenericInstruction {
1394   let OutOperandList = (outs type0:$dst0, variable_ops);
1395   let InOperandList = (ins type1:$src);
1396   let hasSideEffects = false;
1397   let variadicOpsType = type0;
1398 }
1399 
1400 // Insert a smaller register into a larger one at the specified bit-index.
1401 def G_INSERT : GenericInstruction {
1402   let OutOperandList = (outs type0:$dst);
1403   let InOperandList = (ins type0:$src, type1:$op, untyped_imm_0:$offset);
1404   let hasSideEffects = false;
1405 }
1406 
1407 // Concatenate multiple registers of the same size into a wider register.
1408 // The input operands are always ordered from lowest bits to highest:
1409 //   %0:(s32) = G_MERGE_VALUES %bits_0_7:(s8), %bits_8_15:(s8),
1410 //                             %bits_16_23:(s8), %bits_24_31:(s8)
1411 def G_MERGE_VALUES : GenericInstruction {
1412   let OutOperandList = (outs type0:$dst);
1413   let InOperandList = (ins type1:$src0, variable_ops);
1414   let hasSideEffects = false;
1415   let variadicOpsType = type1;
1416 }
1417 
1418 // Generic vscale.
1419 // Puts the value of the runtime vscale multiplied by the value in the source
1420 // operand into the destination register.
1421 def G_VSCALE : GenericInstruction {
1422   let OutOperandList = (outs type0:$dst);
1423   let InOperandList = (ins unknown:$src);
1424   let hasSideEffects = false;
1425 }
1426 
1427 /// Create a vector from multiple scalar registers. No implicit
1428 /// conversion is performed (i.e. the result element type must be the
1429 /// same as all source operands)
1430 def G_BUILD_VECTOR : GenericInstruction {
1431   let OutOperandList = (outs type0:$dst);
1432   let InOperandList = (ins type1:$src0, variable_ops);
1433   let hasSideEffects = false;
1434   let variadicOpsType = type1;
1435 }
1436 
1437 /// Like G_BUILD_VECTOR, but truncates the larger operand types to fit the
1438 /// destination vector elt type.
1439 def G_BUILD_VECTOR_TRUNC : GenericInstruction {
1440   let OutOperandList = (outs type0:$dst);
1441   let InOperandList = (ins type1:$src0, variable_ops);
1442   let hasSideEffects = false;
1443 }
1444 
1445 /// Create a vector by concatenating vectors together.
1446 def G_CONCAT_VECTORS : GenericInstruction {
1447   let OutOperandList = (outs type0:$dst);
1448   let InOperandList = (ins type1:$src0, variable_ops);
1449   let hasSideEffects = false;
1450 }
1451 
1452 // Intrinsic without side effects.
1453 def G_INTRINSIC : GenericInstruction {
1454   let OutOperandList = (outs);
1455   let InOperandList = (ins unknown:$intrin, variable_ops);
1456   let hasSideEffects = false;
1457 }
1458 
1459 // Intrinsic with side effects.
1460 def G_INTRINSIC_W_SIDE_EFFECTS : GenericInstruction {
1461   let OutOperandList = (outs);
1462   let InOperandList = (ins unknown:$intrin, variable_ops);
1463   let hasSideEffects = true;
1464   let mayLoad = true;
1465   let mayStore = true;
1466 }
1467 
1468 // Convergent intrinsic without side effects.
1469 def G_INTRINSIC_CONVERGENT : GenericInstruction {
1470   let OutOperandList = (outs);
1471   let InOperandList = (ins unknown:$intrin, variable_ops);
1472   let hasSideEffects = false;
1473   let isConvergent = true;
1474 }
1475 
1476 // Convergent intrinsic with side effects.
1477 def G_INTRINSIC_CONVERGENT_W_SIDE_EFFECTS : GenericInstruction {
1478   let OutOperandList = (outs);
1479   let InOperandList = (ins unknown:$intrin, variable_ops);
1480   let hasSideEffects = true;
1481   let mayLoad = true;
1482   let mayStore = true;
1483   let isConvergent = true;
1484 }
1485 
1486 //------------------------------------------------------------------------------
1487 // Branches.
1488 //------------------------------------------------------------------------------
1489 
1490 // Generic unconditional branch.
1491 def G_BR : GenericInstruction {
1492   let OutOperandList = (outs);
1493   let InOperandList = (ins unknown:$src1);
1494   let hasSideEffects = false;
1495   let isBranch = true;
1496   let isTerminator = true;
1497   let isBarrier = true;
1498 }
1499 
1500 // Generic conditional branch.
1501 def G_BRCOND : GenericInstruction {
1502   let OutOperandList = (outs);
1503   let InOperandList = (ins type0:$tst, unknown:$truebb);
1504   let hasSideEffects = false;
1505   let isBranch = true;
1506   let isTerminator = true;
1507 }
1508 
1509 // Generic indirect branch.
1510 def G_BRINDIRECT : GenericInstruction {
1511   let OutOperandList = (outs);
1512   let InOperandList = (ins type0:$src1);
1513   let hasSideEffects = false;
1514   let isBranch = true;
1515   let isTerminator = true;
1516   let isBarrier = true;
1517   let isIndirectBranch = true;
1518 }
1519 
1520 // Generic branch to jump table entry
1521 def G_BRJT : GenericInstruction {
1522   let OutOperandList = (outs);
1523   let InOperandList = (ins ptype0:$tbl, unknown:$jti, type1:$idx);
1524   let hasSideEffects = false;
1525   let isBranch = true;
1526   let isTerminator = true;
1527   let isBarrier = true;
1528   let isIndirectBranch = true;
1529 }
1530 
1531 // A marker to signal the following code is an invoke region, that may throw
1532 // an exception and therefore not return.
1533 def G_INVOKE_REGION_START : GenericInstruction {
1534   let OutOperandList = (outs);
1535   let InOperandList = (ins);
1536   let isTerminator = true; // This must be a terminator.
1537   let hasSideEffects = false;
1538 }
1539 
1540 def G_READ_REGISTER : GenericInstruction {
1541   let OutOperandList = (outs type0:$dst);
1542   let InOperandList = (ins unknown:$register);
1543   let hasSideEffects = true;
1544 
1545   // Assume convergent. It's probably not worth the effort of somehow
1546   // modeling convergent and nonconvergent register accesses.
1547   let isConvergent = true;
1548 }
1549 
1550 def G_WRITE_REGISTER : GenericInstruction {
1551   let OutOperandList = (outs);
1552   let InOperandList = (ins unknown:$register, type0:$value);
1553   let hasSideEffects = true;
1554 
1555   // Assume convergent. It's probably not worth the effort of somehow
1556   // modeling convergent and nonconvergent register accesses.
1557   let isConvergent = true;
1558 }
1559 
1560 //------------------------------------------------------------------------------
1561 // Vector ops
1562 //------------------------------------------------------------------------------
1563 
1564 // Generic insert subvector.
1565 def G_INSERT_SUBVECTOR : GenericInstruction {
1566   let OutOperandList = (outs type0:$dst);
1567   let InOperandList = (ins type0:$src0, type1:$src1, untyped_imm_0:$idx);
1568   let hasSideEffects = false;
1569 }
1570 
1571 // Generic extract subvector.
1572 def G_EXTRACT_SUBVECTOR : GenericInstruction {
1573   let OutOperandList = (outs type0:$dst);
1574   let InOperandList = (ins type1:$src, untyped_imm_0:$idx);
1575   let hasSideEffects = false;
1576 }
1577 
1578 // Generic insertelement.
1579 def G_INSERT_VECTOR_ELT : GenericInstruction {
1580   let OutOperandList = (outs type0:$dst);
1581   let InOperandList = (ins type0:$src, type1:$elt, type2:$idx);
1582   let hasSideEffects = false;
1583 }
1584 
1585 // Generic extractelement.
1586 def G_EXTRACT_VECTOR_ELT : GenericInstruction {
1587   let OutOperandList = (outs type0:$dst);
1588   let InOperandList = (ins type1:$src, type2:$idx);
1589   let hasSideEffects = false;
1590 }
1591 
1592 // Generic shufflevector.
1593 //
1594 // The mask operand should be an IR Constant which exactly matches the
1595 // corresponding mask for the IR shufflevector instruction.
1596 def G_SHUFFLE_VECTOR: GenericInstruction {
1597   let OutOperandList = (outs type0:$dst);
1598   let InOperandList = (ins type1:$v1, type1:$v2, unknown:$mask);
1599   let hasSideEffects = false;
1600 }
1601 
1602 // Generic splatvector.
1603 def G_SPLAT_VECTOR: GenericInstruction {
1604   let OutOperandList = (outs type0:$dst);
1605   let InOperandList = (ins type1:$val);
1606   let hasSideEffects = false;
1607 }
1608 
1609 // Generic stepvector.
1610 def G_STEP_VECTOR: GenericInstruction {
1611   let OutOperandList = (outs type0:$dst);
1612   let InOperandList = (ins unknown:$step);
1613   let hasSideEffects = false;
1614 }
1615 
1616 // Generic masked compress.
1617 def G_VECTOR_COMPRESS: GenericInstruction {
1618   let OutOperandList = (outs type0:$dst);
1619   let InOperandList = (ins type0:$vec, type1:$mask, type0:$passthru);
1620   let hasSideEffects = false;
1621 }
1622 
1623 //------------------------------------------------------------------------------
1624 // Vector reductions
1625 //------------------------------------------------------------------------------
1626 
1627 class VectorReduction : GenericInstruction {
1628   let OutOperandList = (outs type0:$dst);
1629   let InOperandList = (ins type1:$v);
1630   let hasSideEffects = false;
1631 }
1632 
1633 def G_VECREDUCE_SEQ_FADD : GenericInstruction {
1634   let OutOperandList = (outs type0:$dst);
1635   let InOperandList = (ins type1:$acc, type2:$v);
1636   let hasSideEffects = false;
1637 }
1638 
1639 def G_VECREDUCE_SEQ_FMUL : GenericInstruction {
1640   let OutOperandList = (outs type0:$dst);
1641   let InOperandList = (ins type1:$acc, type2:$v);
1642   let hasSideEffects = false;
1643 }
1644 
1645 def G_VECREDUCE_FADD : VectorReduction;
1646 def G_VECREDUCE_FMUL : VectorReduction;
1647 
1648 def G_VECREDUCE_FMAX : VectorReduction;
1649 def G_VECREDUCE_FMIN : VectorReduction;
1650 def G_VECREDUCE_FMAXIMUM : VectorReduction;
1651 def G_VECREDUCE_FMINIMUM : VectorReduction;
1652 
1653 def G_VECREDUCE_ADD : VectorReduction;
1654 def G_VECREDUCE_MUL : VectorReduction;
1655 def G_VECREDUCE_AND : VectorReduction;
1656 def G_VECREDUCE_OR : VectorReduction;
1657 def G_VECREDUCE_XOR : VectorReduction;
1658 def G_VECREDUCE_SMAX : VectorReduction;
1659 def G_VECREDUCE_SMIN : VectorReduction;
1660 def G_VECREDUCE_UMAX : VectorReduction;
1661 def G_VECREDUCE_UMIN : VectorReduction;
1662 
1663 //------------------------------------------------------------------------------
1664 // Constrained floating point ops
1665 //------------------------------------------------------------------------------
1666 
1667 def G_STRICT_FADD : ConstrainedInstruction<G_FADD>;
1668 def G_STRICT_FSUB : ConstrainedInstruction<G_FSUB>;
1669 def G_STRICT_FMUL : ConstrainedInstruction<G_FMUL>;
1670 def G_STRICT_FDIV : ConstrainedInstruction<G_FDIV>;
1671 def G_STRICT_FREM : ConstrainedInstruction<G_FREM>;
1672 def G_STRICT_FMA : ConstrainedInstruction<G_FMA>;
1673 def G_STRICT_FSQRT : ConstrainedInstruction<G_FSQRT>;
1674 def G_STRICT_FLDEXP : ConstrainedInstruction<G_FLDEXP>;
1675 
1676 //------------------------------------------------------------------------------
1677 // Memory intrinsics
1678 //------------------------------------------------------------------------------
1679 
1680 def G_MEMCPY : GenericInstruction {
1681   let OutOperandList = (outs);
1682   let InOperandList = (ins ptype0:$dst_addr, ptype1:$src_addr, type2:$size, untyped_imm_0:$tailcall);
1683   let hasSideEffects = false;
1684   let mayLoad = true;
1685   let mayStore = true;
1686 }
1687 
1688 def G_MEMCPY_INLINE : GenericInstruction {
1689   let OutOperandList = (outs);
1690   let InOperandList = (ins ptype0:$dst_addr, ptype1:$src_addr, type2:$size);
1691   let hasSideEffects = false;
1692   let mayLoad = true;
1693   let mayStore = true;
1694 }
1695 
1696 def G_MEMMOVE : GenericInstruction {
1697   let OutOperandList = (outs);
1698   let InOperandList = (ins ptype0:$dst_addr, ptype1:$src_addr, type2:$size, untyped_imm_0:$tailcall);
1699   let hasSideEffects = false;
1700   let mayLoad = true;
1701   let mayStore = true;
1702 }
1703 
1704 def G_MEMSET : GenericInstruction {
1705   let OutOperandList = (outs);
1706   let InOperandList = (ins ptype0:$dst_addr, type1:$value, type2:$size, untyped_imm_0:$tailcall);
1707   let hasSideEffects = false;
1708   let mayStore = true;
1709 }
1710 
1711 def G_BZERO : GenericInstruction {
1712   let OutOperandList = (outs);
1713   let InOperandList = (ins ptype0:$dst_addr, type1:$size, untyped_imm_0:$tailcall);
1714   let hasSideEffects = false;
1715   let mayStore = true;
1716 }
1717 
1718 //------------------------------------------------------------------------------
1719 // Trap intrinsics
1720 //------------------------------------------------------------------------------
1721 def G_TRAP : GenericInstruction {
1722   let OutOperandList = (outs);
1723   let InOperandList = (ins);
1724   let hasSideEffects = true;
1725   let mayStore = true;
1726 }
1727 
1728 def G_DEBUGTRAP : GenericInstruction {
1729   let OutOperandList = (outs);
1730   let InOperandList = (ins);
1731   let hasSideEffects = true;
1732 }
1733 
1734 def G_UBSANTRAP : GenericInstruction {
1735   let OutOperandList = (outs);
1736   let InOperandList = (ins i8imm:$kind);
1737   let hasSideEffects = true;
1738 }
1739 
1740 //------------------------------------------------------------------------------
1741 // Bitfield extraction.
1742 //------------------------------------------------------------------------------
1743 
1744 // Generic signed bitfield extraction. The operands are in the range
1745 // 0 <= lsb < lsb + width <= src bitwidth, where all values are unsigned.
1746 def G_SBFX : GenericInstruction {
1747   let OutOperandList = (outs type0:$dst);
1748   let InOperandList = (ins type0:$src, type1:$lsb, type1:$width);
1749   let hasSideEffects = false;
1750 }
1751 
1752 // Generic unsigned bitfield extraction. The operands are in the range
1753 // 0 <= lsb < lsb + width <= src bitwidth, where all values are unsigned.
1754 def G_UBFX : GenericInstruction {
1755   let OutOperandList = (outs type0:$dst);
1756   let InOperandList = (ins type0:$src, type1:$lsb, type1:$width);
1757   let hasSideEffects = false;
1758 }
1759 
1760 //------------------------------------------------------------------------------
1761 // Optimization hints
1762 //------------------------------------------------------------------------------
1763 
1764 // Asserts that an operation has already been zero-extended from a specific
1765 // type.
1766 def G_ASSERT_ZEXT : GenericInstruction {
1767   let OutOperandList = (outs type0:$dst);
1768   let InOperandList = (ins type0:$src, untyped_imm_0:$sz);
1769   let hasSideEffects = false;
1770 }
1771 
1772 // Asserts that an operation has already been sign-extended from a specific
1773 // type.
1774 def G_ASSERT_SEXT : GenericInstruction {
1775   let OutOperandList = (outs type0:$dst);
1776   let InOperandList = (ins type0:$src, untyped_imm_0:$sz);
1777   let hasSideEffects = false;
1778 }
1779 
1780 // Asserts that a value has at least the given alignment.
1781 def G_ASSERT_ALIGN : GenericInstruction {
1782   let OutOperandList = (outs type0:$dst);
1783   let InOperandList = (ins type0:$src, untyped_imm_0:$align);
1784   let hasSideEffects = false;
1785 }
1786 
1787 // Prevent constant folding of the source value with any users.
1788 def G_CONSTANT_FOLD_BARRIER : GenericInstruction {
1789   let OutOperandList = (outs type0:$dst);
1790   let InOperandList = (ins type0:$src);
1791   let hasSideEffects = false;
1792 }