123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443 |
- //===-- GenericOpcodes.td - Opcodes used with GlobalISel ---*- tablegen -*-===//
- //
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
- // See https://llvm.org/LICENSE.txt for license information.
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- //
- //===----------------------------------------------------------------------===//
- //
- // This file defines the generic opcodes used with GlobalISel.
- // After instruction selection, these opcodes should not appear.
- //
- //===----------------------------------------------------------------------===//
- //------------------------------------------------------------------------------
- // Unary ops.
- //------------------------------------------------------------------------------
- class GenericInstruction : StandardPseudoInstruction {
- let isPreISelOpcode = true;
- }
- // Provide a variant of an instruction with the same operands, but
- // different instruction flags. This is intended to provide a
- // convenient way to define strict floating point variants of ordinary
- // floating point instructions.
- class ConstrainedIntruction<GenericInstruction baseInst> :
- GenericInstruction {
- let OutOperandList = baseInst.OutOperandList;
- let InOperandList = baseInst.InOperandList;
- let isCommutable = baseInst.isCommutable;
- // TODO: Do we need a better way to mark reads from FP mode than
- // hasSideEffects?
- let hasSideEffects = true;
- let mayRaiseFPException = true;
- }
- // Extend the underlying scalar type of an operation, leaving the high bits
- // unspecified.
- def G_ANYEXT : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type1:$src);
- let hasSideEffects = false;
- }
- // Sign extend the underlying scalar type of an operation, copying the sign bit
- // into the newly-created space.
- def G_SEXT : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type1:$src);
- let hasSideEffects = false;
- }
- // Sign extend the a value from an arbitrary bit position, copying the sign bit
- // into all bits above it. This is equivalent to a shl + ashr pair with an
- // appropriate shift amount. $sz is an immediate (MachineOperand::isImm()
- // returns true) to allow targets to have some bitwidths legal and others
- // lowered. This opcode is particularly useful if the target has sign-extension
- // instructions that are cheaper than the constituent shifts as the optimizer is
- // able to make decisions on whether it's better to hang on to the G_SEXT_INREG
- // or to lower it and optimize the individual shifts.
- def G_SEXT_INREG : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src, untyped_imm_0:$sz);
- let hasSideEffects = false;
- }
- // Zero extend the underlying scalar type of an operation, putting zero bits
- // into the newly-created space.
- def G_ZEXT : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type1:$src);
- let hasSideEffects = false;
- }
- // Truncate the underlying scalar type of an operation. This is equivalent to
- // G_EXTRACT for scalar types, but acts elementwise on vectors.
- def G_TRUNC : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type1:$src);
- let hasSideEffects = false;
- }
- def G_IMPLICIT_DEF : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins);
- let hasSideEffects = false;
- }
- def G_PHI : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins variable_ops);
- let hasSideEffects = false;
- }
- def G_FRAME_INDEX : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins unknown:$src2);
- let hasSideEffects = false;
- }
- def G_GLOBAL_VALUE : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins unknown:$src);
- let hasSideEffects = false;
- }
- def G_INTTOPTR : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type1:$src);
- let hasSideEffects = false;
- }
- def G_PTRTOINT : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type1:$src);
- let hasSideEffects = false;
- }
- def G_BITCAST : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type1:$src);
- let hasSideEffects = false;
- }
- // Only supports scalar result types
- def G_CONSTANT : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins unknown:$imm);
- let hasSideEffects = false;
- }
- // Only supports scalar result types
- def G_FCONSTANT : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins unknown:$imm);
- let hasSideEffects = false;
- }
- def G_VASTART : GenericInstruction {
- let OutOperandList = (outs);
- let InOperandList = (ins type0:$list);
- let hasSideEffects = false;
- let mayStore = true;
- }
- def G_VAARG : GenericInstruction {
- let OutOperandList = (outs type0:$val);
- let InOperandList = (ins type1:$list, unknown:$align);
- let hasSideEffects = false;
- let mayLoad = true;
- let mayStore = true;
- }
- def G_CTLZ : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type1:$src);
- let hasSideEffects = false;
- }
- def G_CTLZ_ZERO_UNDEF : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type1:$src);
- let hasSideEffects = false;
- }
- def G_CTTZ : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type1:$src);
- let hasSideEffects = false;
- }
- def G_CTTZ_ZERO_UNDEF : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type1:$src);
- let hasSideEffects = false;
- }
- def G_CTPOP : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type1:$src);
- let hasSideEffects = false;
- }
- def G_BSWAP : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src);
- let hasSideEffects = false;
- }
- def G_BITREVERSE : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src);
- let hasSideEffects = false;
- }
- def G_ADDRSPACE_CAST : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type1:$src);
- let hasSideEffects = false;
- }
- def G_BLOCK_ADDR : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins unknown:$ba);
- let hasSideEffects = false;
- }
- def G_JUMP_TABLE : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins unknown:$jti);
- let hasSideEffects = false;
- }
- def G_DYN_STACKALLOC : GenericInstruction {
- let OutOperandList = (outs ptype0:$dst);
- let InOperandList = (ins type1:$size, i32imm:$align);
- let hasSideEffects = true;
- }
- def G_FREEZE : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src);
- let hasSideEffects = false;
- }
- def G_LROUND: GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type1:$src);
- let hasSideEffects = false;
- }
- def G_LLROUND: GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type1:$src);
- let hasSideEffects = false;
- }
- //------------------------------------------------------------------------------
- // Binary ops.
- //------------------------------------------------------------------------------
- // Generic addition.
- def G_ADD : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
- let isCommutable = true;
- }
- // Generic subtraction.
- def G_SUB : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
- let isCommutable = false;
- }
- // Generic multiplication.
- def G_MUL : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
- let isCommutable = true;
- }
- // Generic signed division.
- def G_SDIV : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
- let isCommutable = false;
- }
- // Generic unsigned division.
- def G_UDIV : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
- let isCommutable = false;
- }
- // Generic signed remainder.
- def G_SREM : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
- let isCommutable = false;
- }
- // Generic unsigned remainder.
- def G_UREM : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
- let isCommutable = false;
- }
- // Generic signed division and remainder.
- def G_SDIVREM : GenericInstruction {
- let OutOperandList = (outs type0:$div, type0:$rem);
- let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
- let isCommutable = false;
- }
- // Generic unsigned division and remainder.
- def G_UDIVREM : GenericInstruction {
- let OutOperandList = (outs type0:$div, type0:$rem);
- let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
- let isCommutable = false;
- }
- // Generic bitwise and.
- def G_AND : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
- let isCommutable = true;
- }
- // Generic bitwise or.
- def G_OR : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
- let isCommutable = true;
- }
- // Generic bitwise xor.
- def G_XOR : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
- let isCommutable = true;
- }
- // Generic left-shift.
- def G_SHL : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src1, type1:$src2);
- let hasSideEffects = false;
- }
- // Generic logical right-shift.
- def G_LSHR : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src1, type1:$src2);
- let hasSideEffects = false;
- }
- // Generic arithmetic right-shift.
- def G_ASHR : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src1, type1:$src2);
- let hasSideEffects = false;
- }
- /// Funnel 'double' shifts take 3 operands, 2 inputs and the shift amount.
- /// fshl(X,Y,Z): (X << (Z % bitwidth)) | (Y >> (bitwidth - (Z % bitwidth)))
- def G_FSHL : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src1, type0:$src2, type1:$src3);
- let hasSideEffects = false;
- }
- /// Funnel 'double' shifts take 3 operands, 2 inputs and the shift amount.
- /// fshr(X,Y,Z): (X << (bitwidth - (Z % bitwidth))) | (Y >> (Z % bitwidth))
- def G_FSHR : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src1, type0:$src2, type1:$src3);
- let hasSideEffects = false;
- }
- /// Rotate bits right.
- def G_ROTR : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src1, type1:$src2);
- let hasSideEffects = false;
- }
- /// Rotate bits left.
- def G_ROTL : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src1, type1:$src2);
- let hasSideEffects = false;
- }
- // Generic integer comparison.
- def G_ICMP : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins unknown:$tst, type1:$src1, type1:$src2);
- let hasSideEffects = false;
- }
- // Generic floating-point comparison.
- def G_FCMP : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins unknown:$tst, type1:$src1, type1:$src2);
- let hasSideEffects = false;
- }
- // Generic select
- def G_SELECT : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type1:$tst, type0:$src1, type0:$src2);
- let hasSideEffects = false;
- }
- // Generic pointer offset.
- def G_PTR_ADD : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src1, type1:$src2);
- let hasSideEffects = false;
- }
- // Generic pointer mask. type1 should be an integer with the same
- // bitwidth as the pointer type.
- def G_PTRMASK : GenericInstruction {
- let OutOperandList = (outs ptype0:$dst);
- let InOperandList = (ins ptype0:$src, type1:$bits);
- let hasSideEffects = false;
- }
- // Generic signed integer minimum.
- def G_SMIN : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
- let isCommutable = true;
- }
- // Generic signed integer maximum.
- def G_SMAX : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
- let isCommutable = true;
- }
- // Generic unsigned integer minimum.
- def G_UMIN : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
- let isCommutable = true;
- }
- // Generic unsigned integer maximum.
- def G_UMAX : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
- let isCommutable = true;
- }
- // Generic integer absolute value.
- def G_ABS : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src);
- let hasSideEffects = false;
- }
- //------------------------------------------------------------------------------
- // Overflow ops
- //------------------------------------------------------------------------------
- // Generic unsigned addition producing a carry flag.
- def G_UADDO : GenericInstruction {
- let OutOperandList = (outs type0:$dst, type1:$carry_out);
- let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
- let isCommutable = true;
- }
- // Generic unsigned addition consuming and producing a carry flag.
- def G_UADDE : GenericInstruction {
- let OutOperandList = (outs type0:$dst, type1:$carry_out);
- let InOperandList = (ins type0:$src1, type0:$src2, type1:$carry_in);
- let hasSideEffects = false;
- }
- // Generic signed addition producing a carry flag.
- def G_SADDO : GenericInstruction {
- let OutOperandList = (outs type0:$dst, type1:$carry_out);
- let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
- let isCommutable = true;
- }
- // Generic signed addition consuming and producing a carry flag.
- def G_SADDE : GenericInstruction {
- let OutOperandList = (outs type0:$dst, type1:$carry_out);
- let InOperandList = (ins type0:$src1, type0:$src2, type1:$carry_in);
- let hasSideEffects = false;
- }
- // Generic unsigned subtraction producing a carry flag.
- def G_USUBO : GenericInstruction {
- let OutOperandList = (outs type0:$dst, type1:$carry_out);
- let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
- }
- // Generic unsigned subtraction consuming and producing a carry flag.
- def G_USUBE : GenericInstruction {
- let OutOperandList = (outs type0:$dst, type1:$carry_out);
- let InOperandList = (ins type0:$src1, type0:$src2, type1:$carry_in);
- let hasSideEffects = false;
- }
- // Generic signed subtraction producing a carry flag.
- def G_SSUBO : GenericInstruction {
- let OutOperandList = (outs type0:$dst, type1:$carry_out);
- let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
- }
- // Generic signed subtraction consuming and producing a carry flag.
- def G_SSUBE : GenericInstruction {
- let OutOperandList = (outs type0:$dst, type1:$carry_out);
- let InOperandList = (ins type0:$src1, type0:$src2, type1:$carry_in);
- let hasSideEffects = false;
- }
- // Generic unsigned multiplication producing a carry flag.
- def G_UMULO : GenericInstruction {
- let OutOperandList = (outs type0:$dst, type1:$carry_out);
- let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
- let isCommutable = true;
- }
- // Generic signed multiplication producing a carry flag.
- def G_SMULO : GenericInstruction {
- let OutOperandList = (outs type0:$dst, type1:$carry_out);
- let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
- let isCommutable = true;
- }
- // Multiply two numbers at twice the incoming bit width (unsigned) and return
- // the high half of the result.
- def G_UMULH : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
- let isCommutable = true;
- }
- // Multiply two numbers at twice the incoming bit width (signed) and return
- // the high half of the result.
- def G_SMULH : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
- let isCommutable = true;
- }
- //------------------------------------------------------------------------------
- // Saturating ops
- //------------------------------------------------------------------------------
- // Generic saturating unsigned addition.
- def G_UADDSAT : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
- let isCommutable = true;
- }
- // Generic saturating signed addition.
- def G_SADDSAT : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
- let isCommutable = true;
- }
- // Generic saturating unsigned subtraction.
- def G_USUBSAT : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
- let isCommutable = false;
- }
- // Generic saturating signed subtraction.
- def G_SSUBSAT : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
- let isCommutable = false;
- }
- // Generic saturating unsigned left shift.
- def G_USHLSAT : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src1, type1:$src2);
- let hasSideEffects = false;
- let isCommutable = false;
- }
- // Generic saturating signed left shift.
- def G_SSHLSAT : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src1, type1:$src2);
- let hasSideEffects = false;
- let isCommutable = false;
- }
- /// RESULT = [US]MULFIX(LHS, RHS, SCALE) - Perform fixed point
- /// multiplication on 2 integers with the same width and scale. SCALE
- /// represents the scale of both operands as fixed point numbers. This
- /// SCALE parameter must be a constant integer. A scale of zero is
- /// effectively performing multiplication on 2 integers.
- def G_SMULFIX : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src0, type0:$src1, untyped_imm_0:$scale);
- let hasSideEffects = false;
- let isCommutable = true;
- }
- def G_UMULFIX : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src0, type0:$src1, untyped_imm_0:$scale);
- let hasSideEffects = false;
- let isCommutable = true;
- }
- /// Same as the corresponding unsaturated fixed point instructions, but the
- /// result is clamped between the min and max values representable by the
- /// bits of the first 2 operands.
- def G_SMULFIXSAT : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src0, type0:$src1, untyped_imm_0:$scale);
- let hasSideEffects = false;
- let isCommutable = true;
- }
- def G_UMULFIXSAT : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src0, type0:$src1, untyped_imm_0:$scale);
- let hasSideEffects = false;
- let isCommutable = true;
- }
- /// RESULT = [US]DIVFIX(LHS, RHS, SCALE) - Perform fixed point division on
- /// 2 integers with the same width and scale. SCALE represents the scale
- /// of both operands as fixed point numbers. This SCALE parameter must be a
- /// constant integer.
- def G_SDIVFIX : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src0, type0:$src1, untyped_imm_0:$scale);
- let hasSideEffects = false;
- let isCommutable = false;
- }
- def G_UDIVFIX : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src0, type0:$src1, untyped_imm_0:$scale);
- let hasSideEffects = false;
- let isCommutable = false;
- }
- /// Same as the corresponding unsaturated fixed point instructions,
- /// but the result is clamped between the min and max values
- /// representable by the bits of the first 2 operands.
- def G_SDIVFIXSAT : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src0, type0:$src1, untyped_imm_0:$scale);
- let hasSideEffects = false;
- let isCommutable = false;
- }
- def G_UDIVFIXSAT : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src0, type0:$src1, untyped_imm_0:$scale);
- let hasSideEffects = false;
- let isCommutable = false;
- }
- //------------------------------------------------------------------------------
- // Floating Point Unary Ops.
- //------------------------------------------------------------------------------
- def G_FNEG : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src);
- let hasSideEffects = false;
- }
- def G_FPEXT : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type1:$src);
- let hasSideEffects = false;
- }
- def G_FPTRUNC : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type1:$src);
- let hasSideEffects = false;
- }
- def G_FPTOSI : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type1:$src);
- let hasSideEffects = false;
- }
- def G_FPTOUI : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type1:$src);
- let hasSideEffects = false;
- }
- def G_SITOFP : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type1:$src);
- let hasSideEffects = false;
- }
- def G_UITOFP : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type1:$src);
- let hasSideEffects = false;
- }
- def G_FABS : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src);
- let hasSideEffects = false;
- }
- def G_FCOPYSIGN : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src0, type1:$src1);
- let hasSideEffects = false;
- }
- def G_FCANONICALIZE : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src);
- let hasSideEffects = false;
- }
- // FMINNUM/FMAXNUM - Perform floating-point minimum or maximum on two
- // values.
- //
- // In the case where a single input is a NaN (either signaling or quiet),
- // the non-NaN input is returned.
- //
- // The return value of (FMINNUM 0.0, -0.0) could be either 0.0 or -0.0.
- def G_FMINNUM : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
- let isCommutable = true;
- }
- def G_FMAXNUM : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
- let isCommutable = true;
- }
- // FMINNUM_IEEE/FMAXNUM_IEEE - Perform floating-point minimum or maximum on
- // two values, following the IEEE-754 2008 definition. This differs from
- // FMINNUM/FMAXNUM in the handling of signaling NaNs. If one input is a
- // signaling NaN, returns a quiet NaN.
- def G_FMINNUM_IEEE : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
- let isCommutable = true;
- }
- def G_FMAXNUM_IEEE : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
- let isCommutable = true;
- }
- // FMINIMUM/FMAXIMUM - NaN-propagating minimum/maximum that also treat -0.0
- // as less than 0.0. While FMINNUM_IEEE/FMAXNUM_IEEE follow IEEE 754-2008
- // semantics, FMINIMUM/FMAXIMUM follow IEEE 754-2018 draft semantics.
- def G_FMINIMUM : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
- let isCommutable = true;
- }
- def G_FMAXIMUM : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
- let isCommutable = true;
- }
- //------------------------------------------------------------------------------
- // Floating Point Binary ops.
- //------------------------------------------------------------------------------
- // Generic FP addition.
- def G_FADD : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
- let isCommutable = true;
- }
- // Generic FP subtraction.
- def G_FSUB : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
- let isCommutable = false;
- }
- // Generic FP multiplication.
- def G_FMUL : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
- let isCommutable = true;
- }
- // Generic fused multiply-add instruction.
- // Behaves like llvm fma intrinsic ie src1 * src2 + src3
- def G_FMA : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src1, type0:$src2, type0:$src3);
- let hasSideEffects = false;
- let isCommutable = false;
- }
- /// Generic FP multiply and add. Perform a * b + c, while getting the
- /// same result as the separately rounded operations, unlike G_FMA.
- def G_FMAD : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src1, type0:$src2, type0:$src3);
- let hasSideEffects = false;
- let isCommutable = false;
- }
- // Generic FP division.
- def G_FDIV : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
- }
- // Generic FP remainder.
- def G_FREM : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
- }
- // Floating point exponentiation.
- def G_FPOW : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src1, type0:$src2);
- let hasSideEffects = false;
- }
- // Floating point exponentiation, with an integer power.
- def G_FPOWI : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src0, type1:$src1);
- let hasSideEffects = false;
- }
- // Floating point base-e exponential of a value.
- def G_FEXP : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src1);
- let hasSideEffects = false;
- }
- // Floating point base-2 exponential of a value.
- def G_FEXP2 : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src1);
- let hasSideEffects = false;
- }
- // Floating point base-e logarithm of a value.
- def G_FLOG : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src1);
- let hasSideEffects = false;
- }
- // Floating point base-2 logarithm of a value.
- def G_FLOG2 : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src1);
- let hasSideEffects = false;
- }
- // Floating point base-10 logarithm of a value.
- def G_FLOG10 : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src1);
- let hasSideEffects = false;
- }
- // Floating point ceiling of a value.
- def G_FCEIL : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src1);
- let hasSideEffects = false;
- }
- // Floating point cosine of a value.
- def G_FCOS : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src1);
- let hasSideEffects = false;
- }
- // Floating point sine of a value.
- def G_FSIN : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src1);
- let hasSideEffects = false;
- }
- // Floating point square root of a value.
- // This returns NaN for negative nonzero values.
- // NOTE: Unlike libm sqrt(), this never sets errno. In all other respects it's
- // libm-conformant.
- def G_FSQRT : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src1);
- let hasSideEffects = false;
- }
- // Floating point floor of a value.
- def G_FFLOOR : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src1);
- let hasSideEffects = false;
- }
- // Floating point round to next integer.
- def G_FRINT : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src1);
- let hasSideEffects = false;
- }
- // Floating point round to the nearest integer.
- def G_FNEARBYINT : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src1);
- let hasSideEffects = false;
- }
- //------------------------------------------------------------------------------
- // Opcodes for LLVM Intrinsics
- //------------------------------------------------------------------------------
- def G_INTRINSIC_TRUNC : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src1);
- let hasSideEffects = false;
- }
- def G_INTRINSIC_ROUND : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src1);
- let hasSideEffects = false;
- }
- def G_INTRINSIC_LRINT : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type1:$src);
- let hasSideEffects = false;
- }
- def G_INTRINSIC_ROUNDEVEN : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src1);
- let hasSideEffects = false;
- }
- def G_READCYCLECOUNTER : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins);
- let hasSideEffects = true;
- }
- //------------------------------------------------------------------------------
- // Memory ops
- //------------------------------------------------------------------------------
- // Generic load. Expects a MachineMemOperand in addition to explicit
- // operands. If the result size is larger than the memory size, the
- // high bits are undefined. If the result is a vector type and larger
- // than the memory size, the high elements are undefined (i.e. this is
- // not a per-element, vector anyextload)
- def G_LOAD : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins ptype1:$addr);
- let hasSideEffects = false;
- let mayLoad = true;
- }
- // Generic sign-extended load. Expects a MachineMemOperand in addition to explicit operands.
- def G_SEXTLOAD : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins ptype1:$addr);
- let hasSideEffects = false;
- let mayLoad = true;
- }
- // Generic zero-extended load. Expects a MachineMemOperand in addition to explicit operands.
- def G_ZEXTLOAD : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins ptype1:$addr);
- let hasSideEffects = false;
- let mayLoad = true;
- }
- // Generic indexed load. Combines a GEP with a load. $newaddr is set to $base + $offset.
- // If $am is 0 (post-indexed), then the value is loaded from $base; if $am is 1 (pre-indexed)
- // then the value is loaded from $newaddr.
- def G_INDEXED_LOAD : GenericInstruction {
- let OutOperandList = (outs type0:$dst, ptype1:$newaddr);
- let InOperandList = (ins ptype1:$base, type2:$offset, unknown:$am);
- let hasSideEffects = false;
- let mayLoad = true;
- }
- // Same as G_INDEXED_LOAD except that the load performed is sign-extending, as with G_SEXTLOAD.
- def G_INDEXED_SEXTLOAD : GenericInstruction {
- let OutOperandList = (outs type0:$dst, ptype1:$newaddr);
- let InOperandList = (ins ptype1:$base, type2:$offset, unknown:$am);
- let hasSideEffects = false;
- let mayLoad = true;
- }
- // Same as G_INDEXED_LOAD except that the load performed is zero-extending, as with G_ZEXTLOAD.
- def G_INDEXED_ZEXTLOAD : GenericInstruction {
- let OutOperandList = (outs type0:$dst, ptype1:$newaddr);
- let InOperandList = (ins ptype1:$base, type2:$offset, unknown:$am);
- let hasSideEffects = false;
- let mayLoad = true;
- }
- // Generic store. Expects a MachineMemOperand in addition to explicit operands.
- def G_STORE : GenericInstruction {
- let OutOperandList = (outs);
- let InOperandList = (ins type0:$src, ptype1:$addr);
- let hasSideEffects = false;
- let mayStore = true;
- }
- // Combines a store with a GEP. See description of G_INDEXED_LOAD for indexing behaviour.
- def G_INDEXED_STORE : GenericInstruction {
- let OutOperandList = (outs ptype0:$newaddr);
- let InOperandList = (ins type1:$src, ptype0:$base, ptype2:$offset,
- unknown:$am);
- let hasSideEffects = false;
- let mayStore = true;
- }
- // Generic atomic cmpxchg with internal success check. Expects a
- // MachineMemOperand in addition to explicit operands.
- def G_ATOMIC_CMPXCHG_WITH_SUCCESS : GenericInstruction {
- let OutOperandList = (outs type0:$oldval, type1:$success);
- let InOperandList = (ins type2:$addr, type0:$cmpval, type0:$newval);
- let hasSideEffects = false;
- let mayLoad = true;
- let mayStore = true;
- }
- // Generic atomic cmpxchg. Expects a MachineMemOperand in addition to explicit
- // operands.
- def G_ATOMIC_CMPXCHG : GenericInstruction {
- let OutOperandList = (outs type0:$oldval);
- let InOperandList = (ins ptype1:$addr, type0:$cmpval, type0:$newval);
- let hasSideEffects = false;
- let mayLoad = true;
- let mayStore = true;
- }
- // Generic atomicrmw. Expects a MachineMemOperand in addition to explicit
- // operands.
- class G_ATOMICRMW_OP : GenericInstruction {
- let OutOperandList = (outs type0:$oldval);
- let InOperandList = (ins ptype1:$addr, type0:$val);
- let hasSideEffects = false;
- let mayLoad = true;
- let mayStore = true;
- }
- def G_ATOMICRMW_XCHG : G_ATOMICRMW_OP;
- def G_ATOMICRMW_ADD : G_ATOMICRMW_OP;
- def G_ATOMICRMW_SUB : G_ATOMICRMW_OP;
- def G_ATOMICRMW_AND : G_ATOMICRMW_OP;
- def G_ATOMICRMW_NAND : G_ATOMICRMW_OP;
- def G_ATOMICRMW_OR : G_ATOMICRMW_OP;
- def G_ATOMICRMW_XOR : G_ATOMICRMW_OP;
- def G_ATOMICRMW_MAX : G_ATOMICRMW_OP;
- def G_ATOMICRMW_MIN : G_ATOMICRMW_OP;
- def G_ATOMICRMW_UMAX : G_ATOMICRMW_OP;
- def G_ATOMICRMW_UMIN : G_ATOMICRMW_OP;
- def G_ATOMICRMW_FADD : G_ATOMICRMW_OP;
- def G_ATOMICRMW_FSUB : G_ATOMICRMW_OP;
- def G_FENCE : GenericInstruction {
- let OutOperandList = (outs);
- let InOperandList = (ins i32imm:$ordering, i32imm:$scope);
- let hasSideEffects = true;
- }
- //------------------------------------------------------------------------------
- // Variadic ops
- //------------------------------------------------------------------------------
- // Extract a register of the specified size, starting from the block given by
- // index. This will almost certainly be mapped to sub-register COPYs after
- // register banks have been selected.
- def G_EXTRACT : GenericInstruction {
- let OutOperandList = (outs type0:$res);
- let InOperandList = (ins type1:$src, untyped_imm_0:$offset);
- let hasSideEffects = false;
- }
- // Extract multiple registers specified size, starting from blocks given by
- // indexes. This will almost certainly be mapped to sub-register COPYs after
- // register banks have been selected.
- // The output operands are always ordered from lowest bits to highest:
- // %bits_0_7:(s8), %bits_8_15:(s8),
- // %bits_16_23:(s8), %bits_24_31:(s8) = G_UNMERGE_VALUES %0:(s32)
- def G_UNMERGE_VALUES : GenericInstruction {
- let OutOperandList = (outs type0:$dst0, variable_ops);
- let InOperandList = (ins type1:$src);
- let hasSideEffects = false;
- }
- // Insert a smaller register into a larger one at the specified bit-index.
- def G_INSERT : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src, type1:$op, untyped_imm_0:$offset);
- let hasSideEffects = false;
- }
- // Concatenate multiple registers of the same size into a wider register.
- // The input operands are always ordered from lowest bits to highest:
- // %0:(s32) = G_MERGE_VALUES %bits_0_7:(s8), %bits_8_15:(s8),
- // %bits_16_23:(s8), %bits_24_31:(s8)
- def G_MERGE_VALUES : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type1:$src0, variable_ops);
- let hasSideEffects = false;
- }
- /// Create a vector from multiple scalar registers. No implicit
- /// conversion is performed (i.e. the result element type must be the
- /// same as all source operands)
- def G_BUILD_VECTOR : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type1:$src0, variable_ops);
- let hasSideEffects = false;
- }
- /// Like G_BUILD_VECTOR, but truncates the larger operand types to fit the
- /// destination vector elt type.
- def G_BUILD_VECTOR_TRUNC : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type1:$src0, variable_ops);
- let hasSideEffects = false;
- }
- /// Create a vector by concatenating vectors together.
- def G_CONCAT_VECTORS : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type1:$src0, variable_ops);
- let hasSideEffects = false;
- }
- // Intrinsic without side effects.
- def G_INTRINSIC : GenericInstruction {
- let OutOperandList = (outs);
- let InOperandList = (ins unknown:$intrin, variable_ops);
- let hasSideEffects = false;
- // Conservatively assume this is convergent. If there turnes out to
- // be a need, there should be separate convergent intrinsic opcodes.
- let isConvergent = 1;
- }
- // Intrinsic with side effects.
- def G_INTRINSIC_W_SIDE_EFFECTS : GenericInstruction {
- let OutOperandList = (outs);
- let InOperandList = (ins unknown:$intrin, variable_ops);
- let hasSideEffects = true;
- let mayLoad = true;
- let mayStore = true;
- // Conservatively assume this is convergent. If there turnes out to
- // be a need, there should be separate convergent intrinsic opcodes.
- let isConvergent = true;
- }
- //------------------------------------------------------------------------------
- // Branches.
- //------------------------------------------------------------------------------
- // Generic unconditional branch.
- def G_BR : GenericInstruction {
- let OutOperandList = (outs);
- let InOperandList = (ins unknown:$src1);
- let hasSideEffects = false;
- let isBranch = true;
- let isTerminator = true;
- let isBarrier = true;
- }
- // Generic conditional branch.
- def G_BRCOND : GenericInstruction {
- let OutOperandList = (outs);
- let InOperandList = (ins type0:$tst, unknown:$truebb);
- let hasSideEffects = false;
- let isBranch = true;
- let isTerminator = true;
- }
- // Generic indirect branch.
- def G_BRINDIRECT : GenericInstruction {
- let OutOperandList = (outs);
- let InOperandList = (ins type0:$src1);
- let hasSideEffects = false;
- let isBranch = true;
- let isTerminator = true;
- let isBarrier = true;
- let isIndirectBranch = true;
- }
- // Generic branch to jump table entry
- def G_BRJT : GenericInstruction {
- let OutOperandList = (outs);
- let InOperandList = (ins ptype0:$tbl, unknown:$jti, type1:$idx);
- let hasSideEffects = false;
- let isBranch = true;
- let isTerminator = true;
- let isBarrier = true;
- let isIndirectBranch = true;
- }
- def G_READ_REGISTER : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins unknown:$register);
- let hasSideEffects = true;
- // Assume convergent. It's probably not worth the effort of somehow
- // modeling convergent and nonconvergent register accesses.
- let isConvergent = true;
- }
- def G_WRITE_REGISTER : GenericInstruction {
- let OutOperandList = (outs);
- let InOperandList = (ins unknown:$register, type0:$value);
- let hasSideEffects = true;
- // Assume convergent. It's probably not worth the effort of somehow
- // modeling convergent and nonconvergent register accesses.
- let isConvergent = true;
- }
- //------------------------------------------------------------------------------
- // Vector ops
- //------------------------------------------------------------------------------
- // Generic insertelement.
- def G_INSERT_VECTOR_ELT : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src, type1:$elt, type2:$idx);
- let hasSideEffects = false;
- }
- // Generic extractelement.
- def G_EXTRACT_VECTOR_ELT : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type1:$src, type2:$idx);
- let hasSideEffects = false;
- }
- // Generic shufflevector.
- //
- // The mask operand should be an IR Constant which exactly matches the
- // corresponding mask for the IR shufflevector instruction.
- def G_SHUFFLE_VECTOR: GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type1:$v1, type1:$v2, unknown:$mask);
- let hasSideEffects = false;
- }
- //------------------------------------------------------------------------------
- // Vector reductions
- //------------------------------------------------------------------------------
- class VectorReduction : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type1:$v);
- let hasSideEffects = false;
- }
- def G_VECREDUCE_SEQ_FADD : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type1:$acc, type2:$v);
- let hasSideEffects = false;
- }
- def G_VECREDUCE_SEQ_FMUL : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type1:$acc, type2:$v);
- let hasSideEffects = false;
- }
- def G_VECREDUCE_FADD : VectorReduction;
- def G_VECREDUCE_FMUL : VectorReduction;
- def G_VECREDUCE_FMAX : VectorReduction;
- def G_VECREDUCE_FMIN : VectorReduction;
- def G_VECREDUCE_ADD : VectorReduction;
- def G_VECREDUCE_MUL : VectorReduction;
- def G_VECREDUCE_AND : VectorReduction;
- def G_VECREDUCE_OR : VectorReduction;
- def G_VECREDUCE_XOR : VectorReduction;
- def G_VECREDUCE_SMAX : VectorReduction;
- def G_VECREDUCE_SMIN : VectorReduction;
- def G_VECREDUCE_UMAX : VectorReduction;
- def G_VECREDUCE_UMIN : VectorReduction;
- //------------------------------------------------------------------------------
- // Constrained floating point ops
- //------------------------------------------------------------------------------
- def G_STRICT_FADD : ConstrainedIntruction<G_FADD>;
- def G_STRICT_FSUB : ConstrainedIntruction<G_FSUB>;
- def G_STRICT_FMUL : ConstrainedIntruction<G_FMUL>;
- def G_STRICT_FDIV : ConstrainedIntruction<G_FDIV>;
- def G_STRICT_FREM : ConstrainedIntruction<G_FREM>;
- def G_STRICT_FMA : ConstrainedIntruction<G_FMA>;
- def G_STRICT_FSQRT : ConstrainedIntruction<G_FSQRT>;
- //------------------------------------------------------------------------------
- // Memory intrinsics
- //------------------------------------------------------------------------------
- def G_MEMCPY : GenericInstruction {
- let OutOperandList = (outs);
- let InOperandList = (ins ptype0:$dst_addr, ptype1:$src_addr, type2:$size, untyped_imm_0:$tailcall);
- let hasSideEffects = false;
- let mayLoad = true;
- let mayStore = true;
- }
- def G_MEMCPY_INLINE : GenericInstruction {
- let OutOperandList = (outs);
- let InOperandList = (ins ptype0:$dst_addr, ptype1:$src_addr, type2:$size);
- let hasSideEffects = false;
- let mayLoad = true;
- let mayStore = true;
- }
- def G_MEMMOVE : GenericInstruction {
- let OutOperandList = (outs);
- let InOperandList = (ins ptype0:$dst_addr, ptype1:$src_addr, type2:$size, untyped_imm_0:$tailcall);
- let hasSideEffects = false;
- let mayLoad = true;
- let mayStore = true;
- }
- def G_MEMSET : GenericInstruction {
- let OutOperandList = (outs);
- let InOperandList = (ins ptype0:$dst_addr, type1:$value, type2:$size, untyped_imm_0:$tailcall);
- let hasSideEffects = false;
- let mayStore = true;
- }
- def G_BZERO : GenericInstruction {
- let OutOperandList = (outs);
- let InOperandList = (ins ptype0:$dst_addr, type1:$size, untyped_imm_0:$tailcall);
- let hasSideEffects = false;
- let mayStore = true;
- }
- //------------------------------------------------------------------------------
- // Bitfield extraction.
- //------------------------------------------------------------------------------
- // Generic signed bitfield extraction. The operands are in the range
- // 0 <= lsb < lsb + width <= src bitwidth, where all values are unsigned.
- def G_SBFX : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src, type1:$lsb, type1:$width);
- let hasSideEffects = false;
- }
- // Generic unsigned bitfield extraction. The operands are in the range
- // 0 <= lsb < lsb + width <= src bitwidth, where all values are unsigned.
- def G_UBFX : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src, type1:$lsb, type1:$width);
- let hasSideEffects = false;
- }
- //------------------------------------------------------------------------------
- // Optimization hints
- //------------------------------------------------------------------------------
- // Asserts that an operation has already been zero-extended from a specific
- // type.
- def G_ASSERT_ZEXT : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src, untyped_imm_0:$sz);
- let hasSideEffects = false;
- }
- // Asserts that an operation has already been sign-extended from a specific
- // type.
- def G_ASSERT_SEXT : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src, untyped_imm_0:$sz);
- let hasSideEffects = false;
- }
- // Asserts that a value has at least the given alignment.
- def G_ASSERT_ALIGN : GenericInstruction {
- let OutOperandList = (outs type0:$dst);
- let InOperandList = (ins type0:$src, untyped_imm_0:$align);
- let hasSideEffects = false;
- }
|