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 }