13449 lines · plain
1//===- AArch64InstrFormats.td - AArch64 Instruction Formats --*- tblgen -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9//===----------------------------------------------------------------------===//10// Describe AArch64 instructions format here11//12 13// Format specifies the encoding used by the instruction. This is part of the14// ad-hoc solution used to emit machine instruction encodings by our machine15// code emitter.16class Format<bits<2> val> {17 bits<2> Value = val;18}19 20def PseudoFrm : Format<0>;21def NormalFrm : Format<1>; // Do we need any others?22 23// Enum describing whether an instruction is24// destructive in its first source operand.25class DestructiveInstTypeEnum<bits<4> val> {26 bits<4> Value = val;27}28def NotDestructive : DestructiveInstTypeEnum<0>;29// Destructive in its first operand and can be MOVPRFX'd, but has no other30// special properties.31def DestructiveOther : DestructiveInstTypeEnum<1>;32def DestructiveUnary : DestructiveInstTypeEnum<2>;33def DestructiveBinaryImm : DestructiveInstTypeEnum<3>;34def DestructiveBinaryShImmUnpred : DestructiveInstTypeEnum<4>;35def DestructiveBinary : DestructiveInstTypeEnum<5>;36def DestructiveBinaryComm : DestructiveInstTypeEnum<6>;37def DestructiveBinaryCommWithRev : DestructiveInstTypeEnum<7>;38def DestructiveTernaryCommWithRev : DestructiveInstTypeEnum<8>;39 40// 3 inputs unpredicated (reg1, reg2, imm).41// Can be MOVPRFX'd iff reg1 == reg2.42def Destructive2xRegImmUnpred : DestructiveInstTypeEnum<9>;43 44def DestructiveUnaryPassthru : DestructiveInstTypeEnum<10>;45 46class FalseLanesEnum<bits<2> val> {47 bits<2> Value = val;48}49def FalseLanesNone : FalseLanesEnum<0>;50def FalseLanesZero : FalseLanesEnum<1>;51def FalseLanesUndef : FalseLanesEnum<2>;52 53class SMEMatrixTypeEnum<bits<3> val> {54 bits<3> Value = val;55}56def SMEMatrixNone : SMEMatrixTypeEnum<0>;57def SMEMatrixTileB : SMEMatrixTypeEnum<1>;58def SMEMatrixTileH : SMEMatrixTypeEnum<2>;59def SMEMatrixTileS : SMEMatrixTypeEnum<3>;60def SMEMatrixTileD : SMEMatrixTypeEnum<4>;61def SMEMatrixTileQ : SMEMatrixTypeEnum<5>;62def SMEMatrixArray : SMEMatrixTypeEnum<6>;63 64// AArch64 Instruction Format65class AArch64Inst<Format f, string cstr> : Instruction {66 field bits<32> Inst; // Instruction encoding.67 // Mask of bits that cause an encoding to be UNPREDICTABLE.68 // If a bit is set, then if the corresponding bit in the69 // target encoding differs from its value in the "Inst" field,70 // the instruction is UNPREDICTABLE (SoftFail in abstract parlance).71 field bits<32> Unpredictable = 0;72 // SoftFail is the generic name for this field, but we alias it so73 // as to make it more obvious what it means in ARM-land.74 field bits<32> SoftFail = Unpredictable;75 let Namespace = "AArch64";76 Format F = f;77 bits<2> Form = F.Value;78 79 // Defaults80 bit isWhile = 0;81 bit isPTestLike = 0;82 FalseLanesEnum FalseLanes = FalseLanesNone;83 DestructiveInstTypeEnum DestructiveInstType = NotDestructive;84 SMEMatrixTypeEnum SMEMatrixType = SMEMatrixNone;85 ElementSizeEnum ElementSize = ElementSizeNone;86 87 let TSFlags{13-11} = SMEMatrixType.Value;88 let TSFlags{10} = isPTestLike;89 let TSFlags{9} = isWhile;90 let TSFlags{8-7} = FalseLanes.Value;91 let TSFlags{6-3} = DestructiveInstType.Value;92 let TSFlags{2-0} = ElementSize.Value;93 94 let Pattern = [];95 let Constraints = cstr;96}97 98class InstSubst<string Asm, dag Result, bit EmitPriority = 0>99 : InstAlias<Asm, Result, EmitPriority>, Requires<[UseNegativeImmediates]>;100 101// Pseudo instructions (don't have encoding information)102class Pseudo<dag oops, dag iops, list<dag> pattern, string cstr = "">103 : AArch64Inst<PseudoFrm, cstr> {104 dag OutOperandList = oops;105 dag InOperandList = iops;106 let Pattern = pattern;107 let isCodeGenOnly = 1;108 let isPseudo = 1;109}110 111// Real instructions (have encoding information)112class EncodedI<string cstr, list<dag> pattern> : AArch64Inst<NormalFrm, cstr> {113 let Pattern = pattern;114 let Size = 4;115}116 117// Normal instructions118class I<dag oops, dag iops, string asm, string operands, string cstr,119 list<dag> pattern>120 : EncodedI<cstr, pattern> {121 dag OutOperandList = oops;122 dag InOperandList = iops;123 let AsmString = !strconcat(asm, operands);124}125 126class TriOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$MHS, node:$RHS), res>;127class BinOpFrag<dag res> : PatFrag<(ops node:$LHS, node:$RHS), res>;128class UnOpFrag<dag res> : PatFrag<(ops node:$LHS), res>;129 130// Helper fragment for an extract of the high portion of a 128-bit vector. The131// ComplexPattern match both extract_subvector and bitcast(extract_subvector(..)).132def extract_high_v16i8 :133 ComplexPattern<v8i8, 1, "SelectExtractHigh", [extract_subvector, bitconvert]>;134def extract_high_v8i16 :135 ComplexPattern<v4i16, 1, "SelectExtractHigh", [extract_subvector, bitconvert]>;136def extract_high_v4i32 :137 ComplexPattern<v2i32, 1, "SelectExtractHigh", [extract_subvector, bitconvert]>;138def extract_high_v2i64 :139 ComplexPattern<v1i64, 1, "SelectExtractHigh", [extract_subvector, bitconvert]>;140 141def gi_extract_high_v16i8 :142 GIComplexOperandMatcher<v8s8, "selectExtractHigh">,143 GIComplexPatternEquiv<extract_high_v16i8>;144def gi_extract_high_v8i16 :145 GIComplexOperandMatcher<v4s16, "selectExtractHigh">,146 GIComplexPatternEquiv<extract_high_v8i16>;147def gi_extract_high_v4i32 :148 GIComplexOperandMatcher<v2s32, "selectExtractHigh">,149 GIComplexPatternEquiv<extract_high_v4i32>;150 151def extract_high_v8f16 :152 ComplexPattern<v4f16, 1, "SelectExtractHigh", [extract_subvector, bitconvert]>;153def extract_high_v8bf16 :154 ComplexPattern<v4bf16, 1, "SelectExtractHigh", [extract_subvector, bitconvert]>;155def extract_high_v4f32 :156 ComplexPattern<v2f32, 1, "SelectExtractHigh", [extract_subvector, bitconvert]>;157def extract_high_v2f64 :158 ComplexPattern<v1f64, 1, "SelectExtractHigh", [extract_subvector, bitconvert]>;159 160def gi_extract_high_v8f16 :161 GIComplexOperandMatcher<v4s16, "selectExtractHigh">,162 GIComplexPatternEquiv<extract_high_v8f16>;163def gi_extract_high_v4f32 :164 GIComplexOperandMatcher<v2s32, "selectExtractHigh">,165 GIComplexPatternEquiv<extract_high_v4f32>;166 167def extract_high_dup_v8i16 :168 BinOpFrag<(extract_subvector (v8i16 (AArch64duplane16 (v8i16 node:$LHS), node:$RHS)), (i64 4))>;169def extract_high_dup_v4i32 :170 BinOpFrag<(extract_subvector (v4i32 (AArch64duplane32 (v4i32 node:$LHS), node:$RHS)), (i64 2))>;171 172def dup_v8i16 :173 PatFrags<(ops node:$LHS, node:$RHS),174 [(v4i16 (extract_subvector (v8i16 (AArch64duplane16 (v8i16 node:$LHS), node:$RHS)), (i64 0))),175 (v4i16 (AArch64duplane16 (v8i16 node:$LHS), node:$RHS))]>;176def dup_v4i32 :177 PatFrags<(ops node:$LHS, node:$RHS),178 [(v2i32 (extract_subvector (v4i32 (AArch64duplane32 (v4i32 node:$LHS), node:$RHS)), (i64 0))),179 (v2i32 (AArch64duplane32 (v4i32 node:$LHS), node:$RHS))]>;180def dup_v8f16 :181 PatFrags<(ops node:$LHS, node:$RHS),182 [(v4f16 (extract_subvector (v8f16 (AArch64duplane16 (v8f16 node:$LHS), node:$RHS)), (i64 0))),183 (v4f16 (AArch64duplane16 (v8f16 node:$LHS), node:$RHS))]>;184def dup_v4f32 :185 PatFrags<(ops node:$LHS, node:$RHS),186 [(v2f32 (extract_subvector (v4f32 (AArch64duplane32 (v4f32 node:$LHS), node:$RHS)), (i64 0))),187 (v2f32 (AArch64duplane32 (v4f32 node:$LHS), node:$RHS))]>;188 189// Match either a scalar_to_vector (from SDAG) or a vector_insert of undef (from GISel)190def vec_ins_or_scal_vec : PatFrags<(ops node:$src),191 [(vector_insert undef, node:$src, (i64 0)),192 (scalar_to_vector node:$src)]>;193 194//===----------------------------------------------------------------------===//195// Asm Operand Classes.196//197 198// Shifter operand for arithmetic shifted encodings.199def ShifterOperand : AsmOperandClass {200 let Name = "Shifter";201}202 203// Shifter operand for mov immediate encodings.204def MovImm32ShifterOperand : AsmOperandClass {205 let SuperClasses = [ShifterOperand];206 let Name = "MovImm32Shifter";207 let RenderMethod = "addShifterOperands";208 let DiagnosticType = "InvalidMovImm32Shift";209}210def MovImm64ShifterOperand : AsmOperandClass {211 let SuperClasses = [ShifterOperand];212 let Name = "MovImm64Shifter";213 let RenderMethod = "addShifterOperands";214 let DiagnosticType = "InvalidMovImm64Shift";215}216 217// Shifter operand for arithmetic register shifted encodings.218class ArithmeticShifterOperand<int width> : AsmOperandClass {219 let SuperClasses = [ShifterOperand];220 let Name = "ArithmeticShifter" # width;221 let PredicateMethod = "isArithmeticShifter<" # width # ">";222 let RenderMethod = "addShifterOperands";223 let DiagnosticType = "AddSubRegShift" # width;224}225 226def ArithmeticShifterOperand32 : ArithmeticShifterOperand<32>;227def ArithmeticShifterOperand64 : ArithmeticShifterOperand<64>;228 229// Shifter operand for logical register shifted encodings.230class LogicalShifterOperand<int width> : AsmOperandClass {231 let SuperClasses = [ShifterOperand];232 let Name = "LogicalShifter" # width;233 let PredicateMethod = "isLogicalShifter<" # width # ">";234 let RenderMethod = "addShifterOperands";235 let DiagnosticType = "AddSubRegShift" # width;236}237 238def LogicalShifterOperand32 : LogicalShifterOperand<32>;239def LogicalShifterOperand64 : LogicalShifterOperand<64>;240 241// Shifter operand for logical vector 128/64-bit shifted encodings.242def LogicalVecShifterOperand : AsmOperandClass {243 let SuperClasses = [ShifterOperand];244 let Name = "LogicalVecShifter";245 let RenderMethod = "addShifterOperands";246}247def LogicalVecHalfWordShifterOperand : AsmOperandClass {248 let SuperClasses = [LogicalVecShifterOperand];249 let Name = "LogicalVecHalfWordShifter";250 let RenderMethod = "addShifterOperands";251}252 253// The "MSL" shifter on the vector MOVI instruction.254def MoveVecShifterOperand : AsmOperandClass {255 let SuperClasses = [ShifterOperand];256 let Name = "MoveVecShifter";257 let RenderMethod = "addShifterOperands";258}259 260// Extend operand for arithmetic encodings.261def ExtendOperand : AsmOperandClass {262 let Name = "Extend";263 let DiagnosticType = "AddSubRegExtendLarge";264}265def ExtendOperand64 : AsmOperandClass {266 let SuperClasses = [ExtendOperand];267 let Name = "Extend64";268 let DiagnosticType = "AddSubRegExtendSmall";269}270// 'extend' that's a lsl of a 64-bit register.271def ExtendOperandLSL64 : AsmOperandClass {272 let SuperClasses = [ExtendOperand];273 let Name = "ExtendLSL64";274 let RenderMethod = "addExtend64Operands";275 let DiagnosticType = "AddSubRegExtendLarge";276}277 278// 8-bit floating-point immediate encodings.279def FPImmOperand : AsmOperandClass {280 let Name = "FPImm";281 let ParserMethod = "tryParseFPImm<true>";282 let DiagnosticType = "InvalidFPImm";283}284 285def CondCode : AsmOperandClass {286 let Name = "CondCode";287 let DiagnosticType = "InvalidCondCode";288}289 290// A 32-bit register parsed as 64-bit291def GPR32as64Operand : AsmOperandClass {292 let Name = "GPR32as64";293 let ParserMethod =294 "tryParseGPROperand<false, RegConstraintEqualityTy::EqualsSubReg>";295}296def GPR32as64 : RegisterOperand<GPR32> {297 let ParserMatchClass = GPR32as64Operand;298}299 300// A 64-bit register parsed as 32-bit301def GPR64as32Operand : AsmOperandClass {302 let Name = "GPR64as32";303 let ParserMethod =304 "tryParseGPROperand<false, RegConstraintEqualityTy::EqualsSuperReg>";305}306def GPR64as32 : RegisterOperand<GPR64, "printGPR64as32"> {307 let ParserMatchClass = GPR64as32Operand;308}309 310// 8-bit immediate for AdvSIMD where 64-bit values of the form:311// aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh312// are encoded as the eight bit value 'abcdefgh'.313def SIMDImmType10Operand : AsmOperandClass { let Name = "SIMDImmType10"; }314 315class UImmScaledMemoryIndexed<int Width, int Scale> : AsmOperandClass {316 let Name = "UImm" # Width # "s" # Scale;317 let DiagnosticType = "InvalidMemoryIndexed" # Scale # "UImm" # Width;318 let RenderMethod = "addImmScaledOperands<" # Scale # ">";319 let PredicateMethod = "isUImmScaled<" # Width # ", " # Scale # ">";320}321 322class SImmScaledMemoryIndexed<int Width, int Scale> : AsmOperandClass {323 let Name = "SImm" # Width # "s" # Scale;324 let DiagnosticType = "InvalidMemoryIndexed" # Scale # "SImm" # Width;325 let RenderMethod = "addImmScaledOperands<" # Scale # ">";326 let PredicateMethod = "isSImmScaled<" # Width # ", " # Scale # ">";327}328 329//===----------------------------------------------------------------------===//330// Operand Definitions.331//332 333// ADR[P] instruction labels.334def AdrpOperand : AsmOperandClass {335 let Name = "AdrpLabel";336 let ParserMethod = "tryParseAdrpLabel";337 let DiagnosticType = "InvalidLabel";338}339def adrplabel : Operand<i64> {340 let EncoderMethod = "getAdrLabelOpValue";341 let PrintMethod = "printAdrAdrpLabel";342 let ParserMatchClass = AdrpOperand;343 let OperandType = "OPERAND_PCREL";344}345 346def AdrOperand : AsmOperandClass {347 let Name = "AdrLabel";348 let ParserMethod = "tryParseAdrLabel";349 let DiagnosticType = "InvalidLabel";350}351def adrlabel : Operand<i64> {352 let EncoderMethod = "getAdrLabelOpValue";353 let PrintMethod = "printAdrAdrpLabel";354 let ParserMatchClass = AdrOperand;355 let OperandType = "OPERAND_PCREL";356}357 358class SImmOperand<int width> : AsmOperandClass {359 let Name = "SImm" # width;360 let DiagnosticType = "InvalidMemoryIndexedSImm" # width;361 let RenderMethod = "addImmOperands";362 let PredicateMethod = "isSImm<" # width # ">";363}364 365class AsmImmRange<int Low, int High> : AsmOperandClass {366 let Name = "Imm" # Low # "_" # High;367 let DiagnosticType = "InvalidImm" # Low # "_" # High;368 let RenderMethod = "addImmOperands";369 let PredicateMethod = "isImmInRange<" # Low # "," # High # ">";370}371 372// Authenticated loads for v8.3 can have scaled 10-bit immediate offsets.373def SImm10s8Operand : SImmScaledMemoryIndexed<10, 8>;374def simm10Scaled : Operand<i64> {375 let ParserMatchClass = SImm10s8Operand;376 let DecoderMethod = "DecodeSImm<10>";377 let PrintMethod = "printImmScale<8>";378}379 380def simm9s16 : Operand<i64> {381 let ParserMatchClass = SImmScaledMemoryIndexed<9, 16>;382 let DecoderMethod = "DecodeSImm<9>";383 let PrintMethod = "printImmScale<16>";384}385 386// uimm6 predicate - True if the immediate is in the range [0, 63].387def UImm6Operand : AsmOperandClass {388 let Name = "UImm6";389 let DiagnosticType = "InvalidImm0_63";390}391 392def uimm6 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= 0 && Imm < 64; }]> {393 let ParserMatchClass = UImm6Operand;394}395 396def uimm16 : Operand<i16>, ImmLeaf<i16, [{return Imm >= 0 && Imm < 65536;}]>{397 let ParserMatchClass = AsmImmRange<0, 65535>;398}399 400def uimm6_64b : Operand<i64>, ImmLeaf<i64, [{ return Imm >= 0 && Imm < 64; }]> {401 let ParserMatchClass = UImm6Operand;402}403 404def uimm6_32b : Operand<i32>, ImmLeaf<i32, [{ return Imm >= 0 && Imm < 64; }]> {405 let ParserMatchClass = UImm6Operand;406}407 408def CmpBranchUImm6Operand_32b409 : ComplexPattern<i32, 1, "SelectCmpBranchUImm6Operand", [imm]> {410 let WantsParent = true;411}412 413def CmpBranchUImm6Operand_64b414 : ComplexPattern<i64, 1, "SelectCmpBranchUImm6Operand", [imm]> {415 let WantsParent = true;416}417 418def CmpBranchBExtOperand419 : ComplexPattern<i32, 2, "SelectCmpBranchExtOperand<true>", []> {}420 421def CmpBranchHExtOperand422 : ComplexPattern<i32, 2, "SelectCmpBranchExtOperand<false>", []> {}423 424def UImm6Plus1Operand : AsmOperandClass {425 let Name = "UImm6P1";426 let DiagnosticType = "InvalidImm1_64";427 let RenderMethod = "addImmOperands";428 let ParserMethod = "tryParseAdjImm0_63<-1>";429 let PredicateMethod = "isImmInRange<0,63>";430}431 432def UImm6Minus1Operand : AsmOperandClass {433 let Name = "UImm6M1";434 let DiagnosticType = "InvalidImmM1_62";435 let RenderMethod = "addImmOperands";436 let ParserMethod = "tryParseAdjImm0_63<1>";437 let PredicateMethod = "isImmInRange<0,63>";438}439 440def uimm6p1_32b : Operand<i32> {441 let ParserMatchClass = UImm6Plus1Operand;442}443 444def uimm6p1_64b : Operand<i64> {445 let ParserMatchClass = UImm6Plus1Operand;446}447 448def uimm6m1_32b : Operand<i32> {449 let ParserMatchClass = UImm6Minus1Operand;450}451 452def uimm6m1_64b : Operand<i64> {453 let ParserMatchClass = UImm6Minus1Operand;454}455 456def SImm9Operand : SImmOperand<9>;457def simm9 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -256 && Imm < 256; }]> {458 let ParserMatchClass = SImm9Operand;459 let DecoderMethod = "DecodeSImm<9>";460}461 462// imm0_255 predicate - True if the immediate is in the range [0,255].463def Imm0_255Operand : AsmImmRange<0,255>;464 465def uimm8_32b : Operand<i32>, ImmLeaf<i32, [{ return Imm >= 0 && Imm < 256; }]> {466 let ParserMatchClass = Imm0_255Operand;467}468def uimm8_64b : Operand<i64>, ImmLeaf<i64, [{ return Imm >= 0 && Imm < 256; }]> {469 let ParserMatchClass = Imm0_255Operand;470}471 472def SImm8Operand : SImmOperand<8>;473def simm8_32b : Operand<i32>, ImmLeaf<i32, [{ return Imm >= -128 && Imm < 128; }]> {474 let ParserMatchClass = SImm8Operand;475 let DecoderMethod = "DecodeSImm<8>";476}477def simm8_64b : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -128 && Imm < 128; }]> {478 let ParserMatchClass = SImm8Operand;479 let DecoderMethod = "DecodeSImm<8>";480}481 482def SImm6Operand : SImmOperand<6>;483def simm6_32b : Operand<i32>, ImmLeaf<i32, [{ return Imm >= -32 && Imm < 32; }]> {484 let ParserMatchClass = SImm6Operand;485 let DecoderMethod = "DecodeSImm<6>";486}487 488def SImm5Operand : SImmOperand<5>;489def simm5_64b : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -16 && Imm < 16; }]> {490 let ParserMatchClass = SImm5Operand;491 let DecoderMethod = "DecodeSImm<5>";492}493 494def simm5_32b : Operand<i32>, ImmLeaf<i32, [{ return Imm >= -16 && Imm < 16; }]> {495 let ParserMatchClass = SImm5Operand;496 let DecoderMethod = "DecodeSImm<5>";497}498 499def simm5_8b : Operand<i32>, ImmLeaf<i32, [{ return (int8_t)Imm >= -16 && (int8_t)Imm < 16; }]> {500 let ParserMatchClass = SImm5Operand;501 let DecoderMethod = "DecodeSImm<5>";502 let PrintMethod = "printSImm<8>";503}504 505def simm5_16b : Operand<i32>, ImmLeaf<i32, [{ return (int16_t)Imm >= -16 && (int16_t)Imm < 16; }]> {506 let ParserMatchClass = SImm5Operand;507 let DecoderMethod = "DecodeSImm<5>";508 let PrintMethod = "printSImm<16>";509}510 511// simm7sN predicate - True if the immediate is a multiple of N in the range512// [-64 * N, 63 * N].513 514def SImm7s4Operand : SImmScaledMemoryIndexed<7, 4>;515def SImm7s8Operand : SImmScaledMemoryIndexed<7, 8>;516def SImm7s16Operand : SImmScaledMemoryIndexed<7, 16>;517 518def simm7s4 : Operand<i32> {519 let ParserMatchClass = SImm7s4Operand;520 let PrintMethod = "printImmScale<4>";521}522 523def simm7s8 : Operand<i32> {524 let ParserMatchClass = SImm7s8Operand;525 let PrintMethod = "printImmScale<8>";526}527 528def simm7s16 : Operand<i32> {529 let ParserMatchClass = SImm7s16Operand;530 let PrintMethod = "printImmScale<16>";531}532 533def am_sve_fi : ComplexPattern<iPTR, 2, "SelectAddrModeFrameIndexSVE", []>;534 535def am_indexed7s8 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed7S8", []>;536def am_indexed7s16 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed7S16", []>;537def am_indexed7s32 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed7S32", []>;538def am_indexed7s64 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed7S64", []>;539def am_indexed7s128 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed7S128", []>;540 541def am_indexedu6s128 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedU6S128", []>;542def am_indexeds9s128 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedS9S128", []>;543 544def UImmS1XForm : SDNodeXForm<imm, [{545 return CurDAG->getTargetConstant(N->getZExtValue(), SDLoc(N), MVT::i64);546}]>;547def UImmS2XForm : SDNodeXForm<imm, [{548 return CurDAG->getTargetConstant(N->getZExtValue() / 2, SDLoc(N), MVT::i64);549}]>;550def UImmS4XForm : SDNodeXForm<imm, [{551 return CurDAG->getTargetConstant(N->getZExtValue() / 4, SDLoc(N), MVT::i64);552}]>;553def UImmS8XForm : SDNodeXForm<imm, [{554 return CurDAG->getTargetConstant(N->getZExtValue() / 8, SDLoc(N), MVT::i64);555}]>;556 557def UImmM2XForm : SDNodeXForm<imm, [{558 return CurDAG->getTargetConstant(N->getZExtValue() * 2, SDLoc(N), MVT::i32);559}]>;560 561def UImmM4XForm : SDNodeXForm<imm, [{562 return CurDAG->getTargetConstant(N->getZExtValue() * 4, SDLoc(N), MVT::i32);563}]>;564 565def UImmM8XForm : SDNodeXForm<imm, [{566 return CurDAG->getTargetConstant(N->getZExtValue() * 8, SDLoc(N), MVT::i32);567}]>;568 569// uimm5sN predicate - True if the immediate is a multiple of N in the range570// [0 * N, 32 * N].571def UImm5s2Operand : UImmScaledMemoryIndexed<5, 2>;572def UImm5s4Operand : UImmScaledMemoryIndexed<5, 4>;573def UImm5s8Operand : UImmScaledMemoryIndexed<5, 8>;574 575def uimm5s2 : Operand<i64>, ImmLeaf<i64,576 [{ return Imm >= 0 && Imm < (32*2) && ((Imm % 2) == 0); }],577 UImmS2XForm> {578 let ParserMatchClass = UImm5s2Operand;579 let PrintMethod = "printImmScale<2>";580}581def uimm5s4 : Operand<i64>, ImmLeaf<i64,582 [{ return Imm >= 0 && Imm < (32*4) && ((Imm % 4) == 0); }],583 UImmS4XForm> {584 let ParserMatchClass = UImm5s4Operand;585 let PrintMethod = "printImmScale<4>";586}587def uimm5s8 : Operand<i64>, ImmLeaf<i64,588 [{ return Imm >= 0 && Imm < (32*8) && ((Imm % 8) == 0); }],589 UImmS8XForm> {590 let ParserMatchClass = UImm5s8Operand;591 let PrintMethod = "printImmScale<8>";592}593 594// tuimm5sN predicate - similar to uimm5sN, but use TImmLeaf (TargetConstant)595// instead of ImmLeaf (Constant)596def tuimm5s2 : Operand<i64>, TImmLeaf<i64,597 [{ return Imm >= 0 && Imm < (32*2) && ((Imm % 2) == 0); }],598 UImmS2XForm> {599 let ParserMatchClass = UImm5s2Operand;600 let PrintMethod = "printImmScale<2>";601}602def tuimm5s4 : Operand<i64>, TImmLeaf<i64,603 [{ return Imm >= 0 && Imm < (32*4) && ((Imm % 4) == 0); }],604 UImmS4XForm> {605 let ParserMatchClass = UImm5s4Operand;606 let PrintMethod = "printImmScale<4>";607}608def tuimm5s8 : Operand<i64>, TImmLeaf<i64,609 [{ return Imm >= 0 && Imm < (32*8) && ((Imm % 8) == 0); }],610 UImmS8XForm> {611 let ParserMatchClass = UImm5s8Operand;612 let PrintMethod = "printImmScale<8>";613}614 615// uimm6sN predicate - True if the immediate is a multiple of N in the range616// [0 * N, 64 * N].617def UImm6s1Operand : UImmScaledMemoryIndexed<6, 1>;618def UImm6s2Operand : UImmScaledMemoryIndexed<6, 2>;619def UImm6s4Operand : UImmScaledMemoryIndexed<6, 4>;620def UImm6s8Operand : UImmScaledMemoryIndexed<6, 8>;621def UImm6s16Operand : UImmScaledMemoryIndexed<6, 16>;622 623def uimm6s1 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= 0 && Imm < 64; }]> {624 let ParserMatchClass = UImm6s1Operand;625}626def uimm6s2 : Operand<i64>, ImmLeaf<i64,627[{ return Imm >= 0 && Imm < (64*2) && ((Imm % 2) == 0); }]> {628 let PrintMethod = "printImmScale<2>";629 let ParserMatchClass = UImm6s2Operand;630}631def uimm6s4 : Operand<i64>, ImmLeaf<i64,632[{ return Imm >= 0 && Imm < (64*4) && ((Imm % 4) == 0); }]> {633 let PrintMethod = "printImmScale<4>";634 let ParserMatchClass = UImm6s4Operand;635}636def uimm6s8 : Operand<i64>, ImmLeaf<i64,637[{ return Imm >= 0 && Imm < (64*8) && ((Imm % 8) == 0); }]> {638 let PrintMethod = "printImmScale<8>";639 let ParserMatchClass = UImm6s8Operand;640}641def uimm6s16 : Operand<i64>, ImmLeaf<i64,642[{ return Imm >= 0 && Imm < (64*16) && ((Imm % 16) == 0); }]> {643 let PrintMethod = "printImmScale<16>";644 let ParserMatchClass = UImm6s16Operand;645}646 647def SImmS2XForm : SDNodeXForm<imm, [{648 return CurDAG->getTargetConstant(N->getSExtValue() / 2, SDLoc(N), MVT::i64);649}]>;650def SImmS3XForm : SDNodeXForm<imm, [{651 return CurDAG->getTargetConstant(N->getSExtValue() / 3, SDLoc(N), MVT::i64);652}]>;653def SImmS4XForm : SDNodeXForm<imm, [{654 return CurDAG->getTargetConstant(N->getSExtValue() / 4, SDLoc(N), MVT::i64);655}]>;656def SImmS16XForm : SDNodeXForm<imm, [{657 return CurDAG->getTargetConstant(N->getSExtValue() / 16, SDLoc(N), MVT::i64);658}]>;659def SImmS32XForm : SDNodeXForm<imm, [{660 return CurDAG->getTargetConstant(N->getSExtValue() / 32, SDLoc(N), MVT::i64);661}]>;662 663// simm6sN predicate - True if the immediate is a multiple of N in the range664// [-32 * N, 31 * N].665def SImm6s1Operand : SImmScaledMemoryIndexed<6, 1>;666def simm6s1 : Operand<i64>, ImmLeaf<i64, [{ return Imm >= -32 && Imm < 32; }]> {667 let ParserMatchClass = SImm6s1Operand;668 let DecoderMethod = "DecodeSImm<6>";669}670 671// simm4sN predicate - True if the immediate is a multiple of N in the range672// [ -8* N, 7 * N].673def SImm4s1Operand : SImmScaledMemoryIndexed<4, 1>;674def SImm4s2Operand : SImmScaledMemoryIndexed<4, 2>;675def SImm4s3Operand : SImmScaledMemoryIndexed<4, 3>;676def SImm4s4Operand : SImmScaledMemoryIndexed<4, 4>;677def SImm4s16Operand : SImmScaledMemoryIndexed<4, 16>;678def SImm4s32Operand : SImmScaledMemoryIndexed<4, 32>;679 680def simm4s1 : Operand<i64>, ImmLeaf<i64,681[{ return Imm >=-8 && Imm <= 7; }]> {682 let ParserMatchClass = SImm4s1Operand;683 let DecoderMethod = "DecodeSImm<4>";684}685 686def simm4s2 : Operand<i64>, ImmLeaf<i64,687[{ return Imm >=-16 && Imm <= 14 && (Imm % 2) == 0x0; }], SImmS2XForm> {688 let PrintMethod = "printImmScale<2>";689 let ParserMatchClass = SImm4s2Operand;690 let DecoderMethod = "DecodeSImm<4>";691}692 693def simm4s3 : Operand<i64>, ImmLeaf<i64,694[{ return Imm >=-24 && Imm <= 21 && (Imm % 3) == 0x0; }], SImmS3XForm> {695 let PrintMethod = "printImmScale<3>";696 let ParserMatchClass = SImm4s3Operand;697 let DecoderMethod = "DecodeSImm<4>";698}699 700def simm4s4 : Operand<i64>, ImmLeaf<i64,701[{ return Imm >=-32 && Imm <= 28 && (Imm % 4) == 0x0; }], SImmS4XForm> {702 let PrintMethod = "printImmScale<4>";703 let ParserMatchClass = SImm4s4Operand;704 let DecoderMethod = "DecodeSImm<4>";705}706def simm4s16 : Operand<i64>, ImmLeaf<i64,707[{ return Imm >=-128 && Imm <= 112 && (Imm % 16) == 0x0; }], SImmS16XForm> {708 let PrintMethod = "printImmScale<16>";709 let ParserMatchClass = SImm4s16Operand;710 let DecoderMethod = "DecodeSImm<4>";711}712def simm4s32 : Operand<i64>, ImmLeaf<i64,713[{ return Imm >=-256 && Imm <= 224 && (Imm % 32) == 0x0; }], SImmS32XForm> {714 let PrintMethod = "printImmScale<32>";715 let ParserMatchClass = SImm4s32Operand;716 let DecoderMethod = "DecodeSImm<4>";717}718 719def Imm1_8Operand : AsmImmRange<1, 8>;720def Imm1_16Operand : AsmImmRange<1, 16>;721def Imm1_32Operand : AsmImmRange<1, 32>;722def Imm1_64Operand : AsmImmRange<1, 64>;723 724class BranchTarget<int N> : AsmOperandClass {725 let Name = "BranchTarget" # N;726 let DiagnosticType = "InvalidLabel";727 let PredicateMethod = "isBranchTarget<" # N # ">";728}729 730class PCRelLabel<int N> : BranchTarget<N> {731 let Name = "PCRelLabel" # N;732}733 734def BranchTarget14Operand : BranchTarget<14>;735def BranchTarget26Operand : BranchTarget<26>;736def PCRelLabel19Operand : PCRelLabel<19>;737def PCRelLabel9Operand : PCRelLabel<9>;738 739def MovWSymbolG3AsmOperand : AsmOperandClass {740 let Name = "MovWSymbolG3";741 let RenderMethod = "addImmOperands";742}743 744def movw_symbol_g3 : Operand<i32> {745 let ParserMatchClass = MovWSymbolG3AsmOperand;746}747 748def MovWSymbolG2AsmOperand : AsmOperandClass {749 let Name = "MovWSymbolG2";750 let RenderMethod = "addImmOperands";751}752 753def movw_symbol_g2 : Operand<i32> {754 let ParserMatchClass = MovWSymbolG2AsmOperand;755}756 757def MovWSymbolG1AsmOperand : AsmOperandClass {758 let Name = "MovWSymbolG1";759 let RenderMethod = "addImmOperands";760}761 762def movw_symbol_g1 : Operand<i32> {763 let ParserMatchClass = MovWSymbolG1AsmOperand;764}765 766def MovWSymbolG0AsmOperand : AsmOperandClass {767 let Name = "MovWSymbolG0";768 let RenderMethod = "addImmOperands";769}770 771def movw_symbol_g0 : Operand<i32> {772 let ParserMatchClass = MovWSymbolG0AsmOperand;773}774 775class fixedpoint_i32<ValueType FloatVT>776 : Operand<FloatVT>,777 ComplexPattern<FloatVT, 1, "SelectCVTFixedPosOperand<32>", [fpimm, ld]> {778 let EncoderMethod = "getFixedPointScaleOpValue";779 let DecoderMethod = "DecodeFixedPointScaleImm32";780 let ParserMatchClass = Imm1_32Operand;781}782 783class fixedpoint_i64<ValueType FloatVT>784 : Operand<FloatVT>,785 ComplexPattern<FloatVT, 1, "SelectCVTFixedPosOperand<64>", [fpimm, ld]> {786 let EncoderMethod = "getFixedPointScaleOpValue";787 let DecoderMethod = "DecodeFixedPointScaleImm64";788 let ParserMatchClass = Imm1_64Operand;789}790 791def fixedpoint_f16_i32 : fixedpoint_i32<f16>;792def fixedpoint_f32_i32 : fixedpoint_i32<f32>;793def fixedpoint_f64_i32 : fixedpoint_i32<f64>;794 795def fixedpoint_f16_i64 : fixedpoint_i64<f16>;796def fixedpoint_f32_i64 : fixedpoint_i64<f32>;797def fixedpoint_f64_i64 : fixedpoint_i64<f64>;798 799class fixedpoint_recip_i32<ValueType FloatVT>800 : Operand<FloatVT>,801 ComplexPattern<FloatVT, 1, "SelectCVTFixedPosRecipOperand<32>", [fpimm, ld]> {802 let EncoderMethod = "getFixedPointScaleOpValue";803 let DecoderMethod = "DecodeFixedPointScaleImm32";804}805 806class fixedpoint_recip_i64<ValueType FloatVT>807 : Operand<FloatVT>,808 ComplexPattern<FloatVT, 1, "SelectCVTFixedPosRecipOperand<64>", [fpimm, ld]> {809 let EncoderMethod = "getFixedPointScaleOpValue";810 let DecoderMethod = "DecodeFixedPointScaleImm64";811}812 813def fixedpoint_recip_f16_i32 : fixedpoint_recip_i32<f16>;814def fixedpoint_recip_f32_i32 : fixedpoint_recip_i32<f32>;815def fixedpoint_recip_f64_i32 : fixedpoint_recip_i32<f64>;816 817def fixedpoint_recip_f16_i64 : fixedpoint_recip_i64<f16>;818def fixedpoint_recip_f32_i64 : fixedpoint_recip_i64<f32>;819def fixedpoint_recip_f64_i64 : fixedpoint_recip_i64<f64>;820 821def vecshiftR8 : Operand<i32>, TImmLeaf<i32, [{822 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9);823}]> {824 let EncoderMethod = "getVecShiftR8OpValue";825 let DecoderMethod = "DecodeVecShiftR8Imm";826 let ParserMatchClass = Imm1_8Operand;827}828def vecshiftR16 : Operand<i32>, TImmLeaf<i32, [{829 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17);830}]> {831 let EncoderMethod = "getVecShiftR16OpValue";832 let DecoderMethod = "DecodeVecShiftR16Imm";833 let ParserMatchClass = Imm1_16Operand;834}835def vecshiftR16Narrow : Operand<i32>, TImmLeaf<i32, [{836 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 9);837}]> {838 let EncoderMethod = "getVecShiftR16OpValue";839 let DecoderMethod = "DecodeVecShiftR16ImmNarrow";840 let ParserMatchClass = Imm1_8Operand;841}842def vecshiftR32 : Operand<i32>, TImmLeaf<i32, [{843 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33);844}]> {845 let EncoderMethod = "getVecShiftR32OpValue";846 let DecoderMethod = "DecodeVecShiftR32Imm";847 let ParserMatchClass = Imm1_32Operand;848}849def vecshiftR32Narrow : Operand<i32>, TImmLeaf<i32, [{850 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 17);851}]> {852 let EncoderMethod = "getVecShiftR32OpValue";853 let DecoderMethod = "DecodeVecShiftR32ImmNarrow";854 let ParserMatchClass = Imm1_16Operand;855}856def vecshiftR64 : Operand<i32>, TImmLeaf<i32, [{857 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 65);858}]> {859 let EncoderMethod = "getVecShiftR64OpValue";860 let DecoderMethod = "DecodeVecShiftR64Imm";861 let ParserMatchClass = Imm1_64Operand;862}863def vecshiftR64Narrow : Operand<i32>, TImmLeaf<i32, [{864 return (((uint32_t)Imm) > 0) && (((uint32_t)Imm) < 33);865}]> {866 let EncoderMethod = "getVecShiftR64OpValue";867 let DecoderMethod = "DecodeVecShiftR64ImmNarrow";868 let ParserMatchClass = Imm1_32Operand;869}870 871def Imm0_0Operand : AsmImmRange<0, 0>;872def Imm0_1Operand : AsmImmRange<0, 1>;873def Imm1_1Operand : AsmImmRange<1, 1>;874def Imm0_3Operand : AsmImmRange<0, 3>;875def Imm1_3Operand : AsmImmRange<1, 3>;876def Imm0_7Operand : AsmImmRange<0, 7>;877def Imm1_7Operand : AsmImmRange<1, 7>;878def Imm0_15Operand : AsmImmRange<0, 15>;879def Imm0_31Operand : AsmImmRange<0, 31>;880def Imm0_63Operand : AsmImmRange<0, 63>;881 882def vecshiftL8 : Operand<i32>, TImmLeaf<i32, [{883 return (((uint32_t)Imm) < 8);884}]> {885 let EncoderMethod = "getVecShiftL8OpValue";886 let DecoderMethod = "DecodeVecShiftL8Imm";887 let ParserMatchClass = Imm0_7Operand;888}889def vecshiftL16 : Operand<i32>, TImmLeaf<i32, [{890 return (((uint32_t)Imm) < 16);891}]> {892 let EncoderMethod = "getVecShiftL16OpValue";893 let DecoderMethod = "DecodeVecShiftL16Imm";894 let ParserMatchClass = Imm0_15Operand;895}896def vecshiftL32 : Operand<i32>, TImmLeaf<i32, [{897 return (((uint32_t)Imm) < 32);898}]> {899 let EncoderMethod = "getVecShiftL32OpValue";900 let DecoderMethod = "DecodeVecShiftL32Imm";901 let ParserMatchClass = Imm0_31Operand;902}903def vecshiftL64 : Operand<i32>, TImmLeaf<i32, [{904 return (((uint32_t)Imm) < 64);905}]> {906 let EncoderMethod = "getVecShiftL64OpValue";907 let DecoderMethod = "DecodeVecShiftL64Imm";908 let ParserMatchClass = Imm0_63Operand;909}910 911 912// Crazy immediate formats used by 32-bit and 64-bit logical immediate913// instructions for splatting repeating bit patterns across the immediate.914def logical_imm32_XFORM : SDNodeXForm<imm, [{915 uint64_t enc = AArch64_AM::encodeLogicalImmediate(N->getZExtValue(), 32);916 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);917}]>;918def logical_imm64_XFORM : SDNodeXForm<imm, [{919 uint64_t enc = AArch64_AM::encodeLogicalImmediate(N->getZExtValue(), 64);920 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);921}]>;922 923def gi_logical_imm32_XFORM : GICustomOperandRenderer<"renderLogicalImm32">,924 GISDNodeXFormEquiv<logical_imm32_XFORM>;925def gi_logical_imm64_XFORM : GICustomOperandRenderer<"renderLogicalImm64">,926 GISDNodeXFormEquiv<logical_imm64_XFORM>;927 928let DiagnosticType = "LogicalSecondSource" in {929 def LogicalImm32Operand : AsmOperandClass {930 let Name = "LogicalImm32";931 let PredicateMethod = "isLogicalImm<int32_t>";932 let RenderMethod = "addLogicalImmOperands<int32_t>";933 }934 def LogicalImm64Operand : AsmOperandClass {935 let Name = "LogicalImm64";936 let PredicateMethod = "isLogicalImm<int64_t>";937 let RenderMethod = "addLogicalImmOperands<int64_t>";938 }939 def LogicalImm32NotOperand : AsmOperandClass {940 let Name = "LogicalImm32Not";941 let PredicateMethod = "isLogicalImm<int32_t>";942 let RenderMethod = "addLogicalImmNotOperands<int32_t>";943 }944 def LogicalImm64NotOperand : AsmOperandClass {945 let Name = "LogicalImm64Not";946 let PredicateMethod = "isLogicalImm<int64_t>";947 let RenderMethod = "addLogicalImmNotOperands<int64_t>";948 }949}950 951def Imm0_127Operand : AsmImmRange<0, 127>;952 953let OperandType = "OPERAND_IMMEDIATE" in {954 955def logical_imm32 : Operand<i32>, IntImmLeaf<i32, [{956 return AArch64_AM::isLogicalImmediate(Imm.getZExtValue(), 32);957}], logical_imm32_XFORM> {958 let PrintMethod = "printLogicalImm<int32_t>";959 let ParserMatchClass = LogicalImm32Operand;960}961def logical_imm64 : Operand<i64>, IntImmLeaf<i64, [{962 return AArch64_AM::isLogicalImmediate(Imm.getZExtValue(), 64);963}], logical_imm64_XFORM> {964 let PrintMethod = "printLogicalImm<int64_t>";965 let ParserMatchClass = LogicalImm64Operand;966}967def logical_imm32_not : Operand<i32> {968 let ParserMatchClass = LogicalImm32NotOperand;969}970def logical_imm64_not : Operand<i64> {971 let ParserMatchClass = LogicalImm64NotOperand;972}973 974// immXX_0_65535 predicates - True if the immediate is in the range [0,65535].975let ParserMatchClass = AsmImmRange<0, 65535>, PrintMethod = "printImmHex" in {976def timm32_0_65535 : Operand<i32>, TImmLeaf<i32, [{977 return ((uint32_t)Imm) < 65536;978}]>;979 980def timm64_0_65535 : Operand<i64>, TImmLeaf<i64, [{981 return ((uint64_t)Imm) < 65536;982}]>;983 984def imm64_0_65535 : Operand<i64>, ImmLeaf<i64, [{985 return ((uint64_t)Imm) < 65536;986}]>;987} // ParserMatchClass988 989def imm0_255 : Operand<i32>, ImmLeaf<i32, [{990 return ((uint32_t)Imm) < 256;991}]> {992 let ParserMatchClass = Imm0_255Operand;993 let PrintMethod = "printImm";994}995 996// imm0_127 predicate - True if the immediate is in the range [0,127]997def imm0_127 : Operand<i32>, ImmLeaf<i32, [{998 return ((uint32_t)Imm) < 128;999}]> {1000 let ParserMatchClass = Imm0_127Operand;1001 let PrintMethod = "printImm";1002}1003 1004def imm0_127_64b : Operand<i64>, ImmLeaf<i64, [{1005 return ((uint64_t)Imm) < 128;1006}]> {1007 let ParserMatchClass = Imm0_127Operand;1008 let PrintMethod = "printImm";1009}1010 1011// NOTE: These imm0_N operands have to be of type i64 because i64 is the size1012// for all shift-amounts.1013 1014// imm0_63 predicate - True if the immediate is in the range [0,63]1015def imm0_63 : Operand<i64>, ImmLeaf<i64, [{1016 return ((uint64_t)Imm) < 64;1017}]> {1018 let ParserMatchClass = Imm0_63Operand;1019}1020 1021def timm0_63 : Operand<i64>, TImmLeaf<i64, [{1022 return ((uint64_t)Imm) < 64;1023}]> {1024 let ParserMatchClass = Imm0_63Operand;1025}1026 1027// imm0_31 predicate - True if the immediate is in the range [0,31]1028def imm0_31 : Operand<i64>, ImmLeaf<i64, [{1029 return ((uint64_t)Imm) < 32;1030}]> {1031 let ParserMatchClass = Imm0_31Operand;1032}1033 1034// timm0_31 predicate - same ass imm0_31, but use TargetConstant (TimmLeaf)1035// instead of Constant (ImmLeaf)1036def timm0_31 : Operand<i64>, TImmLeaf<i64, [{1037 return ((uint64_t)Imm) < 32;1038}]> {1039 let ParserMatchClass = Imm0_31Operand;1040}1041 1042// True if the 32-bit immediate is in the range [0,31]1043def imm32_0_31 : Operand<i32>, ImmLeaf<i32, [{1044 return ((uint64_t)Imm) < 32;1045}]> {1046 let ParserMatchClass = Imm0_31Operand;1047}1048 1049// imm0_1 predicate - True if the immediate is in the range [0,1]1050def imm0_1 : Operand<i64>, ImmLeaf<i64, [{1051 return ((uint64_t)Imm) < 2;1052}]> {1053 let ParserMatchClass = Imm0_1Operand;1054}1055 1056// timm0_1 - as above, but use TargetConstant (TImmLeaf)1057def timm0_1 : Operand<i64>, TImmLeaf<i64, [{1058 return ((uint64_t)Imm) < 2;1059}]> {1060 let ParserMatchClass = Imm0_1Operand;1061}1062 1063// timm32_0_0 predicate - True if the 32-bit immediate is in the range [0,0]1064def timm32_0_0 : Operand<i32>, TImmLeaf<i32, [{1065 return ((uint32_t)Imm) == 0;1066}]> {1067 let ParserMatchClass = Imm0_0Operand;1068}1069 1070// timm32_0_1 predicate - True if the 32-bit immediate is in the range [0,1]1071def timm32_0_1 : Operand<i32>, TImmLeaf<i32, [{1072 return ((uint32_t)Imm) < 2;1073}]> {1074 let ParserMatchClass = Imm0_1Operand;1075}1076 1077// extq_timm32_0_1m8 - True if the 32-bit immediate is in the range [0,1], scale this immediate1078// by a factor of 8 after a match is made.1079def extq_timm32_0_1m8 : Operand<i32>, TImmLeaf<i32, [{1080 return ((uint32_t)Imm) < 2;}], UImmM8XForm> {1081 let ParserMatchClass = Imm0_15Operand;1082}1083 1084// timm32_1_1 - True if the 32-bit immediate is in the range [1,1]1085def timm32_1_1 : Operand<i32>, TImmLeaf<i32, [{1086 return ((uint32_t)Imm) == 1;1087}]> {1088 let ParserMatchClass = Imm1_1Operand;1089}1090 1091// timm32_1_3 predicate - True if the 32-bit immediate is in the range [1,3]1092def timm32_1_3 : Operand<i32>, TImmLeaf<i32, [{1093 return ((uint32_t)Imm) > 0 && ((uint32_t)Imm) < 4;1094}]> {1095 let ParserMatchClass = Imm1_3Operand;1096}1097 1098// imm0_15 predicate - True if the immediate is in the range [0,15]1099def imm0_15 : Operand<i64>, ImmLeaf<i64, [{1100 return ((uint64_t)Imm) < 16;1101}]> {1102 let ParserMatchClass = Imm0_15Operand;1103}1104 1105// imm0_7 predicate - True if the immediate is in the range [0,7]1106def imm0_7 : Operand<i64>, ImmLeaf<i64, [{1107 return ((uint64_t)Imm) < 8;1108}]> {1109 let ParserMatchClass = Imm0_7Operand;1110}1111 1112// imm0_3 predicate - True if the immediate is in the range [0,3]1113def imm0_3 : Operand<i64>, ImmLeaf<i64, [{1114 return ((uint64_t)Imm) < 4;1115}]> {1116 let ParserMatchClass = Imm0_3Operand;1117}1118 1119// timm32_0_3 predicate - True if the 32-bit immediate is in the range [0,3]1120def timm32_0_3 : Operand<i32>, TImmLeaf<i32, [{1121 return ((uint32_t)Imm) < 4;1122}]> {1123 let ParserMatchClass = Imm0_3Operand;1124}1125 1126// extq_timm32_0_3m4 - True if the 32-bit immediate is in the range [0,3], scale this immediate1127// by a factor of 4 after a match is made.1128def extq_timm32_0_3m4 : Operand<i32>, TImmLeaf<i32, [{1129 return ((uint32_t)Imm) < 4;}], UImmM4XForm> {1130 let ParserMatchClass = Imm0_15Operand;1131}1132 1133// timm32_0_7 predicate - True if the 32-bit immediate is in the range [0,7]1134def timm32_0_7 : Operand<i32>, TImmLeaf<i32, [{1135 return ((uint32_t)Imm) < 8;1136}]> {1137 let ParserMatchClass = Imm0_7Operand;1138}1139 1140// extq_timm32_0_7m2 - True if the 32-bit immediate is in the range [0,7], scale this immediate1141// by a factor of 2 after a match is made.1142def extq_timm32_0_7m2 : Operand<i32>, TImmLeaf<i32, [{1143 return ((uint32_t)Imm) < 8;}], UImmM2XForm> {1144 let ParserMatchClass = Imm0_15Operand;1145}1146 1147// timm32_1_7 predicate - True if the 32-bit immediate is in the range [1,7]1148def timm32_1_7 : Operand<i32>, TImmLeaf<i32, [{1149 return ((uint32_t)Imm) > 0 && ((uint32_t)Imm) < 8;1150}]> {1151 let ParserMatchClass = Imm1_7Operand;1152}1153 1154// imm32_0_7 predicate - True if the 32-bit immediate is in the range [0,7]1155def imm32_0_7 : Operand<i32>, ImmLeaf<i32, [{1156 return ((uint32_t)Imm) < 8;1157}]> {1158 let ParserMatchClass = Imm0_7Operand;1159}1160 1161// imm32_0_15 predicate - True if the 32-bit immediate is in the range [0,15]1162def imm32_0_15 : Operand<i32>, ImmLeaf<i32, [{1163 return ((uint32_t)Imm) < 16;1164}]> {1165 let ParserMatchClass = Imm0_15Operand;1166}1167 1168// timm32_0_15 predicate - True if the 32-bit immediate is in the range [0,15]1169def timm32_0_15 : Operand<i32>, TImmLeaf<i32, [{1170 return ((uint32_t)Imm) < 16;1171}]> {1172 let ParserMatchClass = Imm0_15Operand;1173}1174 1175// timm32_0_31 predicate - True if the 32-bit immediate is in the range [0,31]1176def timm32_0_31 : Operand<i32>, TImmLeaf<i32, [{1177 return ((uint32_t)Imm) < 32;1178}]> {1179 let ParserMatchClass = Imm0_31Operand;1180}1181 1182// timm32_0_255 predicate - True if the 32-bit immediate is in the range [0,255]1183def timm32_0_255 : Operand<i32>, TImmLeaf<i32, [{1184 return ((uint32_t)Imm) < 256;1185}]> {1186 let ParserMatchClass = Imm0_255Operand;1187}1188 1189} // let OperandType = "OPERAND_IMMEDIATE"1190 1191// An arithmetic shifter operand:1192// {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr1193// {5-0} - imm61194class arith_shift<ValueType Ty, int width> : Operand<Ty> {1195 let PrintMethod = "printShifter";1196 let ParserMatchClass = !cast<AsmOperandClass>(1197 "ArithmeticShifterOperand" # width);1198}1199 1200def arith_shift32 : arith_shift<i32, 32>;1201def arith_shift64 : arith_shift<i64, 64>;1202 1203class arith_shifted_reg<ValueType Ty, RegisterClass regclass, int width>1204 : Operand<Ty>,1205 ComplexPattern<Ty, 2, "SelectArithShiftedRegister", []> {1206 let PrintMethod = "printShiftedRegister";1207 let MIOperandInfo = (ops regclass, !cast<Operand>("arith_shift" # width));1208}1209 1210def arith_shifted_reg32 : arith_shifted_reg<i32, GPR32, 32>;1211def arith_shifted_reg64 : arith_shifted_reg<i64, GPR64, 64>;1212 1213def gi_arith_shifted_reg32 :1214 GIComplexOperandMatcher<s32, "selectArithShiftedRegister">,1215 GIComplexPatternEquiv<arith_shifted_reg32>;1216 1217def gi_arith_shifted_reg64 :1218 GIComplexOperandMatcher<s64, "selectArithShiftedRegister">,1219 GIComplexPatternEquiv<arith_shifted_reg64>;1220 1221// An arithmetic shifter operand:1222// {7-6} - shift type: 00 = lsl, 01 = lsr, 10 = asr, 11 = ror1223// {5-0} - imm61224class logical_shift<int width> : Operand<i32> {1225 let PrintMethod = "printShifter";1226 let ParserMatchClass = !cast<AsmOperandClass>(1227 "LogicalShifterOperand" # width);1228}1229 1230def logical_shift32 : logical_shift<32>;1231def logical_shift64 : logical_shift<64>;1232 1233class logical_shifted_reg<ValueType Ty, RegisterClass regclass, Operand shiftop>1234 : Operand<Ty>,1235 ComplexPattern<Ty, 2, "SelectLogicalShiftedRegister", []> {1236 let PrintMethod = "printShiftedRegister";1237 let MIOperandInfo = (ops regclass, shiftop);1238}1239 1240def logical_shifted_reg32 : logical_shifted_reg<i32, GPR32, logical_shift32>;1241def logical_shifted_reg64 : logical_shifted_reg<i64, GPR64, logical_shift64>;1242 1243def gi_logical_shifted_reg32 :1244 GIComplexOperandMatcher<s32, "selectLogicalShiftedRegister">,1245 GIComplexPatternEquiv<logical_shifted_reg32>;1246 1247def gi_logical_shifted_reg64 :1248 GIComplexOperandMatcher<s64, "selectLogicalShiftedRegister">,1249 GIComplexPatternEquiv<logical_shifted_reg64>;1250 1251// A logical vector shifter operand:1252// {7-6} - shift type: 00 = lsl1253// {5-0} - imm6: #0, #8, #16, or #241254def logical_vec_shift : Operand<i32> {1255 let PrintMethod = "printShifter";1256 let EncoderMethod = "getVecShifterOpValue";1257 let ParserMatchClass = LogicalVecShifterOperand;1258}1259 1260// A logical vector half-word shifter operand:1261// {7-6} - shift type: 00 = lsl1262// {5-0} - imm6: #0 or #81263def logical_vec_hw_shift : Operand<i32> {1264 let PrintMethod = "printShifter";1265 let EncoderMethod = "getVecShifterOpValue";1266 let ParserMatchClass = LogicalVecHalfWordShifterOperand;1267}1268 1269// A vector move shifter operand:1270// {0} - imm1: #8 or #161271def move_vec_shift : Operand<i32> {1272 let PrintMethod = "printShifter";1273 let EncoderMethod = "getMoveVecShifterOpValue";1274 let ParserMatchClass = MoveVecShifterOperand;1275 let OperandType = "OPERAND_SHIFT_MSL";1276 let OperandNamespace = "AArch64";1277}1278 1279let DiagnosticType = "AddSubSecondSource" in {1280 def AddSubImmOperand : AsmOperandClass {1281 let Name = "AddSubImm";1282 let ParserMethod = "tryParseImmWithOptionalShift";1283 let RenderMethod = "addImmWithOptionalShiftOperands<12>";1284 }1285 def AddSubImmNegOperand : AsmOperandClass {1286 let Name = "AddSubImmNeg";1287 let ParserMethod = "tryParseImmWithOptionalShift";1288 let RenderMethod = "addImmNegWithOptionalShiftOperands<12>";1289 }1290}1291// An ADD/SUB immediate shifter operand:1292// second operand:1293// {7-6} - shift type: 00 = lsl1294// {5-0} - imm6: #0 or #121295class addsub_shifted_imm<ValueType Ty>1296 : Operand<Ty>, ComplexPattern<Ty, 2, "SelectArithImmed", [imm]> {1297 let PrintMethod = "printAddSubImm";1298 let EncoderMethod = "getAddSubImmOpValue";1299 let ParserMatchClass = AddSubImmOperand;1300 let MIOperandInfo = (ops i32imm, i32imm);1301}1302 1303class addsub_shifted_imm_neg<ValueType Ty>1304 : Operand<Ty> {1305 let EncoderMethod = "getAddSubImmOpValue";1306 let ParserMatchClass = AddSubImmNegOperand;1307 let MIOperandInfo = (ops i32imm, i32imm);1308}1309 1310def addsub_shifted_imm32 : addsub_shifted_imm<i32>;1311def addsub_shifted_imm64 : addsub_shifted_imm<i64>;1312def addsub_shifted_imm32_neg : addsub_shifted_imm_neg<i32>;1313def addsub_shifted_imm64_neg : addsub_shifted_imm_neg<i64>;1314 1315def gi_addsub_shifted_imm32 :1316 GIComplexOperandMatcher<s32, "selectArithImmed">,1317 GIComplexPatternEquiv<addsub_shifted_imm32>;1318 1319def gi_addsub_shifted_imm64 :1320 GIComplexOperandMatcher<s64, "selectArithImmed">,1321 GIComplexPatternEquiv<addsub_shifted_imm64>;1322 1323class neg_addsub_shifted_imm<ValueType Ty>1324 : Operand<Ty>, ComplexPattern<Ty, 2, "SelectNegArithImmed", [imm]> {1325 let PrintMethod = "printAddSubImm";1326 let EncoderMethod = "getAddSubImmOpValue";1327 let ParserMatchClass = AddSubImmOperand;1328 let MIOperandInfo = (ops i32imm, i32imm);1329}1330 1331def neg_addsub_shifted_imm32 : neg_addsub_shifted_imm<i32>;1332def neg_addsub_shifted_imm64 : neg_addsub_shifted_imm<i64>;1333 1334def gi_neg_addsub_shifted_imm32 :1335 GIComplexOperandMatcher<s32, "selectNegArithImmed">,1336 GIComplexPatternEquiv<neg_addsub_shifted_imm32>;1337 1338def gi_neg_addsub_shifted_imm64 :1339 GIComplexOperandMatcher<s64, "selectNegArithImmed">,1340 GIComplexPatternEquiv<neg_addsub_shifted_imm64>;1341 1342// An extend operand:1343// {5-3} - extend type1344// {2-0} - imm31345def arith_extend : Operand<i32> {1346 let PrintMethod = "printArithExtend";1347 let ParserMatchClass = ExtendOperand;1348}1349def arith_extend64 : Operand<i32> {1350 let PrintMethod = "printArithExtend";1351 let ParserMatchClass = ExtendOperand64;1352}1353 1354// 'extend' that's a lsl of a 64-bit register.1355def arith_extendlsl64 : Operand<i32> {1356 let PrintMethod = "printArithExtend";1357 let ParserMatchClass = ExtendOperandLSL64;1358}1359 1360class arith_extended_reg32<ValueType Ty> : Operand<Ty>,1361 ComplexPattern<Ty, 2, "SelectArithExtendedRegister", []> {1362 let PrintMethod = "printExtendedRegister";1363 let MIOperandInfo = (ops GPR32, arith_extend);1364}1365 1366class arith_extended_reg32to64<ValueType Ty> : Operand<Ty>,1367 ComplexPattern<Ty, 2, "SelectArithExtendedRegister", []> {1368 let PrintMethod = "printExtendedRegister";1369 let MIOperandInfo = (ops GPR32, arith_extend64);1370}1371 1372def arith_extended_reg32_i32 : arith_extended_reg32<i32>;1373def gi_arith_extended_reg32_i32 :1374 GIComplexOperandMatcher<s32, "selectArithExtendedRegister">,1375 GIComplexPatternEquiv<arith_extended_reg32_i32>;1376 1377def arith_extended_reg32_i64 : arith_extended_reg32<i64>;1378def gi_arith_extended_reg32_i64 :1379 GIComplexOperandMatcher<s64, "selectArithExtendedRegister">,1380 GIComplexPatternEquiv<arith_extended_reg32_i64>;1381 1382def arith_extended_reg32to64_i64 : arith_extended_reg32to64<i64>;1383def gi_arith_extended_reg32to64_i64 :1384 GIComplexOperandMatcher<s64, "selectArithExtendedRegister">,1385 GIComplexPatternEquiv<arith_extended_reg32to64_i64>;1386 1387def arith_uxtx : ComplexPattern<i64, 2, "SelectArithUXTXRegister", []>;1388 1389// Floating-point immediate.1390 1391def fpimm16XForm : SDNodeXForm<fpimm, [{1392 uint32_t Enc = AArch64_AM::getFP16Imm(N->getValueAPF());1393 return CurDAG->getTargetConstant(Enc, SDLoc(N), MVT::i32);1394 }]>;1395 1396def fpimm32XForm : SDNodeXForm<fpimm, [{1397 uint32_t Enc = AArch64_AM::getFP32Imm(N->getValueAPF());1398 return CurDAG->getTargetConstant(Enc, SDLoc(N), MVT::i32);1399 }]>;1400 1401def fpimm32SIMDModImmType4XForm : SDNodeXForm<fpimm, [{1402 uint32_t enc = AArch64_AM::encodeAdvSIMDModImmType4(N->getValueAPF()1403 .bitcastToAPInt()1404 .getZExtValue());1405 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);1406 }]>;1407 1408def fpimm64XForm : SDNodeXForm<fpimm, [{1409 uint32_t Enc = AArch64_AM::getFP64Imm(N->getValueAPF());1410 return CurDAG->getTargetConstant(Enc, SDLoc(N), MVT::i32);1411 }]>;1412 1413def fpimm16 : Operand<f16>,1414 FPImmLeaf<f16, [{1415 return AArch64_AM::getFP16Imm(Imm) != -1;1416 }], fpimm16XForm> {1417 let ParserMatchClass = FPImmOperand;1418 let PrintMethod = "printFPImmOperand";1419}1420 1421def fpimmbf16 : Operand<bf16>,1422 FPImmLeaf<bf16, [{1423 return AArch64_AM::getFP16Imm(Imm) != -1;1424 }], fpimm16XForm>;1425 1426def fpimm32 : Operand<f32>,1427 FPImmLeaf<f32, [{1428 return AArch64_AM::getFP32Imm(Imm) != -1;1429 }], fpimm32XForm> {1430 let ParserMatchClass = FPImmOperand;1431 let PrintMethod = "printFPImmOperand";1432}1433 1434def fpimm32SIMDModImmType4 : FPImmLeaf<f32, [{1435 uint64_t Enc = Imm.bitcastToAPInt().getZExtValue();1436 return Enc != 0 && AArch64_AM::isAdvSIMDModImmType4(Enc << 32 | Enc);1437 }], fpimm32SIMDModImmType4XForm> {1438}1439 1440def fpimm64 : Operand<f64>,1441 FPImmLeaf<f64, [{1442 return AArch64_AM::getFP64Imm(Imm) != -1;1443 }], fpimm64XForm> {1444 let ParserMatchClass = FPImmOperand;1445 let PrintMethod = "printFPImmOperand";1446}1447 1448def fpimm8 : Operand<i32> {1449 let ParserMatchClass = FPImmOperand;1450 let PrintMethod = "printFPImmOperand";1451}1452 1453def fpimm0 : FPImmLeaf<fAny, [{1454 return Imm.isExactlyValue(+0.0);1455}]>;1456 1457def fpimm_minus0 : FPImmLeaf<fAny, [{1458 return Imm.isExactlyValue(-0.0);1459}]>;1460 1461def fpimm_half : FPImmLeaf<fAny, [{1462 return Imm.isExactlyValue(+0.5);1463}]>;1464 1465def fpimm_one : FPImmLeaf<fAny, [{1466 return Imm.isExactlyValue(+1.0);1467}]>;1468 1469def fpimm_two : FPImmLeaf<fAny, [{1470 return Imm.isExactlyValue(+2.0);1471}]>;1472 1473def gi_fpimm16 : GICustomOperandRenderer<"renderFPImm16">,1474 GISDNodeXFormEquiv<fpimm16XForm>;1475def gi_fpimm32 : GICustomOperandRenderer<"renderFPImm32">,1476 GISDNodeXFormEquiv<fpimm32XForm>;1477def gi_fpimm64 : GICustomOperandRenderer<"renderFPImm64">,1478 GISDNodeXFormEquiv<fpimm64XForm>;1479def gi_fpimm32SIMDModImmType4 :1480 GICustomOperandRenderer<"renderFPImm32SIMDModImmType4">,1481 GISDNodeXFormEquiv<fpimm32SIMDModImmType4XForm>;1482 1483// Vector lane operands1484class AsmVectorIndex<int Min, int Max, string NamePrefix=""> : AsmOperandClass {1485 let Name = NamePrefix # "IndexRange" # Min # "_" # Max;1486 let DiagnosticType = "Invalid" # Name;1487 let PredicateMethod = "isVectorIndex<" # Min # ", " # Max # ">";1488 let RenderMethod = "addVectorIndexOperands";1489}1490 1491class AsmVectorIndexOpnd<ValueType ty, AsmOperandClass mc>1492 : Operand<ty> {1493 let ParserMatchClass = mc;1494 let PrintMethod = "printVectorIndex";1495}1496 1497multiclass VectorIndex<ValueType ty, AsmOperandClass mc, code pred> {1498 def "" : AsmVectorIndexOpnd<ty, mc>, ImmLeaf<ty, pred>;1499 def _timm : AsmVectorIndexOpnd<ty, mc>, TImmLeaf<ty, pred>;1500}1501 1502def VectorIndex0Operand : AsmVectorIndex<0, 0>;1503def VectorIndex1Operand : AsmVectorIndex<1, 1>;1504def VectorIndexBOperand : AsmVectorIndex<0, 15>;1505def VectorIndexHOperand : AsmVectorIndex<0, 7>;1506def VectorIndexSOperand : AsmVectorIndex<0, 3>;1507def VectorIndexDOperand : AsmVectorIndex<0, 1>;1508 1509let OperandNamespace = "AArch64", OperandType = "OPERAND_IMPLICIT_IMM_0",1510 DecoderMethod = "DecodeZeroImm" in {1511 defm VectorIndex0 : VectorIndex<i64, VectorIndex0Operand,1512 [{ return ((uint64_t)Imm) == 0; }]>;1513 defm VectorIndex032b : VectorIndex<i32, VectorIndex0Operand,1514 [{ return ((uint32_t)Imm) == 0; }]>;1515}1516defm VectorIndex1 : VectorIndex<i64, VectorIndex1Operand,1517 [{ return ((uint64_t)Imm) == 1; }]>;1518defm VectorIndexB : VectorIndex<i64, VectorIndexBOperand,1519 [{ return ((uint64_t)Imm) < 16; }]>;1520defm VectorIndexH : VectorIndex<i64, VectorIndexHOperand,1521 [{ return ((uint64_t)Imm) < 8; }]>;1522defm VectorIndexS : VectorIndex<i64, VectorIndexSOperand,1523 [{ return ((uint64_t)Imm) < 4; }]>;1524defm VectorIndexD : VectorIndex<i64, VectorIndexDOperand,1525 [{ return ((uint64_t)Imm) < 2; }]>;1526 1527defm VectorIndex132b : VectorIndex<i32, VectorIndex1Operand,1528 [{ return ((uint64_t)Imm) == 1; }]>;1529defm VectorIndexB32b : VectorIndex<i32, VectorIndexBOperand,1530 [{ return ((uint64_t)Imm) < 16; }]>;1531defm VectorIndexH32b : VectorIndex<i32, VectorIndexHOperand,1532 [{ return ((uint64_t)Imm) < 8; }]>;1533defm VectorIndexS32b : VectorIndex<i32, VectorIndexSOperand,1534 [{ return ((uint64_t)Imm) < 4; }]>;1535defm VectorIndexD32b : VectorIndex<i32, VectorIndexDOperand,1536 [{ return ((uint64_t)Imm) < 2; }]>;1537 1538def SVEVectorIndexExtDupBOperand : AsmVectorIndex<0, 63, "SVE">;1539def SVEVectorIndexExtDupHOperand : AsmVectorIndex<0, 31, "SVE">;1540def SVEVectorIndexExtDupSOperand : AsmVectorIndex<0, 15, "SVE">;1541def SVEVectorIndexExtDupDOperand : AsmVectorIndex<0, 7, "SVE">;1542def SVEVectorIndexExtDupQOperand : AsmVectorIndex<0, 3, "SVE">;1543 1544defm sve_elm_idx_extdup_b1545 : VectorIndex<i64, SVEVectorIndexExtDupBOperand,1546 [{ return ((uint64_t)Imm) < 64; }]>;1547defm sve_elm_idx_extdup_h1548 : VectorIndex<i64, SVEVectorIndexExtDupHOperand,1549 [{ return ((uint64_t)Imm) < 32; }]>;1550defm sve_elm_idx_extdup_s1551 : VectorIndex<i64, SVEVectorIndexExtDupSOperand,1552 [{ return ((uint64_t)Imm) < 16; }]>;1553defm sve_elm_idx_extdup_d1554 : VectorIndex<i64, SVEVectorIndexExtDupDOperand,1555 [{ return ((uint64_t)Imm) < 8; }]>;1556defm sve_elm_idx_extdup_q1557 : VectorIndex<i64, SVEVectorIndexExtDupQOperand,1558 [{ return ((uint64_t)Imm) < 4; }]>;1559 1560def sme_elm_idx0_0 : Operand<i32>, TImmLeaf<i32, [{1561 return ((uint32_t)Imm) == 0;1562}]> {1563 let ParserMatchClass = Imm0_0Operand;1564 let PrintMethod = "printMatrixIndex";1565 let OperandNamespace = "AArch64";1566 let OperandType = "OPERAND_IMPLICIT_IMM_0";1567 let DecoderMethod = "DecodeZeroImm";1568}1569def sme_elm_idx0_1 : Operand<i32>, TImmLeaf<i32, [{1570 return ((uint32_t)Imm) <= 1;1571}]> {1572 let ParserMatchClass = Imm0_1Operand;1573 let PrintMethod = "printMatrixIndex";1574}1575def sme_elm_idx0_3 : Operand<i32>, TImmLeaf<i32, [{1576 return ((uint32_t)Imm) <= 3;1577}]> {1578 let ParserMatchClass = Imm0_3Operand;1579 let PrintMethod = "printMatrixIndex";1580}1581def sme_elm_idx0_7 : Operand<i32>, TImmLeaf<i32, [{1582 return ((uint32_t)Imm) <= 7;1583}]> {1584 let ParserMatchClass = Imm0_7Operand;1585 let PrintMethod = "printMatrixIndex";1586}1587def sme_elm_idx0_15 : Operand<i32>, TImmLeaf<i32, [{1588 return ((uint32_t)Imm) <= 15;1589}]> {1590 let ParserMatchClass = Imm0_15Operand;1591 let PrintMethod = "printMatrixIndex";1592}1593 1594// SME2 vector select offset operands1595 1596// uimm3s8 predicate1597// True if the immediate is a multiple of 8 in the range [0,56].1598def UImm3s8Operand : UImmScaledMemoryIndexed<3, 8>;1599 1600def uimm3s8 : Operand<i64>, ImmLeaf<i64,1601[{ return Imm >= 0 && Imm <= 56 && ((Imm % 8) == 0); }], UImmS8XForm> {1602 let PrintMethod = "printMatrixIndex<8>";1603 let ParserMatchClass = UImm3s8Operand;1604}1605 1606class UImmScaledMemoryIndexedRange<int Width, int Scale, int OffsetVal> : AsmOperandClass {1607 let Name = "UImm" # Width # "s" # Scale # "Range";1608 let DiagnosticType = "InvalidMemoryIndexedRange" # Scale # "UImm" # Width;1609 let RenderMethod = "addImmScaledRangeOperands<" # Scale # ">";1610 let PredicateMethod = "isUImmScaled<" # Width # ", " # Scale # ", " # OffsetVal # ", /*IsRange=*/true>";1611 let ParserMethod = "tryParseImmRange";1612}1613 1614// Implicit immediate ranges 0:1 and 0:3, scale has no meaning1615// since the immediate is zero1616def UImm0s2RangeOperand : UImmScaledMemoryIndexedRange<0, 2, 1>;1617def UImm0s4RangeOperand : UImmScaledMemoryIndexedRange<0, 4, 3>;1618 1619def UImm1s2RangeOperand : UImmScaledMemoryIndexedRange<1, 2, 1>;1620def UImm1s4RangeOperand : UImmScaledMemoryIndexedRange<1, 4, 3>;1621def UImm2s2RangeOperand : UImmScaledMemoryIndexedRange<2, 2, 1>;1622def UImm2s4RangeOperand : UImmScaledMemoryIndexedRange<2, 4, 3>;1623def UImm3s2RangeOperand : UImmScaledMemoryIndexedRange<3, 2, 1>;1624 1625def uimm0s2range : Operand<i64>, ImmLeaf<i64,1626[{ return Imm == 0; }], UImmS1XForm> {1627 let PrintMethod = "printImmRangeScale<2, 1>";1628 let ParserMatchClass = UImm0s2RangeOperand;1629 let OperandNamespace = "AArch64";1630 let OperandType = "OPERAND_IMPLICIT_IMM_0";1631 let DecoderMethod = "DecodeZeroImm";1632}1633 1634def uimm0s4range : Operand<i64>, ImmLeaf<i64,1635[{ return Imm == 0; }], UImmS1XForm> {1636 let PrintMethod = "printImmRangeScale<4, 3>";1637 let ParserMatchClass = UImm0s4RangeOperand;1638 let OperandNamespace = "AArch64";1639 let OperandType = "OPERAND_IMPLICIT_IMM_0";1640 let DecoderMethod = "DecodeZeroImm";1641}1642 1643def uimm1s2range : Operand<i64>, ImmLeaf<i64,1644[{ return Imm >= 0 && Imm <= 2 && ((Imm % 2) == 0); }], UImmS2XForm> {1645 let PrintMethod = "printImmRangeScale<2, 1>";1646 let ParserMatchClass = UImm1s2RangeOperand;1647}1648 1649def uimm1s4range : Operand<i64>, ImmLeaf<i64,1650[{ return Imm >= 0 && Imm <= 4 && ((Imm % 4) == 0); }], UImmS4XForm> {1651 let PrintMethod = "printImmRangeScale<4, 3>";1652 let ParserMatchClass = UImm1s4RangeOperand;1653}1654 1655def uimm2s2range : Operand<i64>, ImmLeaf<i64,1656[{ return Imm >= 0 && Imm <= 6 && ((Imm % 2) == 0); }], UImmS2XForm> {1657 let PrintMethod = "printImmRangeScale<2, 1>";1658 let ParserMatchClass = UImm2s2RangeOperand;1659}1660 1661def uimm2s4range : Operand<i64>, ImmLeaf<i64,1662[{ return Imm >= 0 && Imm <= 12 && ((Imm % 4) == 0); }], UImmS4XForm> {1663 let PrintMethod = "printImmRangeScale<4, 3>";1664 let ParserMatchClass = UImm2s4RangeOperand;1665}1666 1667def uimm3s2range : Operand<i64>, ImmLeaf<i64,1668[{ return Imm >= 0 && Imm <= 14 && ((Imm % 2) == 0); }], UImmS2XForm> {1669 let PrintMethod = "printImmRangeScale<2, 1>";1670 let ParserMatchClass = UImm3s2RangeOperand;1671}1672 1673 1674// 8-bit immediate for AdvSIMD where 64-bit values of the form:1675// aaaaaaaa bbbbbbbb cccccccc dddddddd eeeeeeee ffffffff gggggggg hhhhhhhh1676// are encoded as the eight bit value 'abcdefgh'.1677def simdimmtype10 : Operand<i32>,1678 FPImmLeaf<f64, [{1679 return AArch64_AM::isAdvSIMDModImmType10(1680 Imm.bitcastToAPInt().getZExtValue());1681 }], SDNodeXForm<fpimm, [{1682 uint32_t enc = AArch64_AM::encodeAdvSIMDModImmType10(N->getValueAPF()1683 .bitcastToAPInt()1684 .getZExtValue());1685 return CurDAG->getTargetConstant(enc, SDLoc(N), MVT::i32);1686 }]>> {1687 let ParserMatchClass = SIMDImmType10Operand;1688 let PrintMethod = "printSIMDType10Operand";1689}1690 1691 1692//---1693// System management1694//---1695 1696// Base encoding for system instruction operands.1697let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in1698class BaseSystemI<bit L, dag oops, dag iops, string asm, string operands,1699 list<dag> pattern = []>1700 : I<oops, iops, asm, operands, "", pattern> {1701 let Inst{31-22} = 0b1101010100;1702 let Inst{21} = L;1703}1704 1705// System instructions which do not have an Rt register.1706class SimpleSystemI<bit L, dag iops, string asm, string operands,1707 list<dag> pattern = []>1708 : BaseSystemI<L, (outs), iops, asm, operands, pattern> {1709 let Inst{4-0} = 0b11111;1710}1711 1712// System instructions which have an Rt register.1713class RtSystemI<bit L, dag oops, dag iops, string asm, string operands,1714 list<dag> pattern = []>1715 : BaseSystemI<L, oops, iops, asm, operands, pattern>,1716 Sched<[WriteSys]> {1717 bits<5> Rt;1718 let Inst{4-0} = Rt;1719}1720 1721// System instructions that pass a register argument1722// This class assumes the register is for input rather than output.1723class RegInputSystemI<bits<4> CRm, bits<3> Op2, string asm,1724 list<dag> pattern = []>1725 : RtSystemI<0, (outs), (ins GPR64:$Rt), asm, "\t$Rt", pattern> {1726 let Inst{20-12} = 0b000110001;1727 let Inst{11-8} = CRm;1728 let Inst{7-5} = Op2;1729}1730 1731class APASI : SimpleSystemI<0, (ins GPR64:$Xt), "apas", "\t$Xt">, Sched<[]> {1732 bits<5> Xt;1733 let Inst{20-5} = 0b0111001110000000;1734 let Inst{4-0} = Xt;1735}1736 1737// Hint instructions that take both a CRm and a 3-bit immediate.1738// NOTE: ideally, this would have mayStore = 0, mayLoad = 0, but we cannot1739// model patterns with sufficiently fine granularity1740let mayStore = 1, mayLoad = 1, hasSideEffects = 1 in1741 class HintI<string mnemonic>1742 : SimpleSystemI<0, (ins imm0_127:$imm), mnemonic#"\t$imm", "",1743 [(int_aarch64_hint imm0_127:$imm)]>,1744 Sched<[WriteHint]> {1745 bits <7> imm;1746 let Inst{20-12} = 0b000110010;1747 let Inst{11-5} = imm;1748 }1749 1750def PHintInstOperand : AsmOperandClass {1751 let Name = "PHint";1752 let ParserMethod = "tryParsePHintInstOperand";1753}1754 1755def phint_op : Operand<i32> {1756 let ParserMatchClass = PHintInstOperand;1757 let PrintMethod = "printPHintOp";1758}1759 1760class STSHHI1761 : SimpleSystemI<0, (ins phint_op:$policy), "stshh", "\t$policy", []>,1762 Sched<[WriteHint]> {1763 bits<3> policy;1764 let Inst{20-12} = 0b000011001;1765 let Inst{11-8} = 0b0110;1766 let Inst{7-5} = policy;1767}1768 1769// System instructions taking a single literal operand which encodes into1770// CRm. op2 differentiates the opcodes.1771def BarrierAsmOperand : AsmOperandClass {1772 let Name = "Barrier";1773 let ParserMethod = "tryParseBarrierOperand";1774}1775def barrier_op : Operand<i32> {1776 let PrintMethod = "printBarrierOption";1777 let ParserMatchClass = BarrierAsmOperand;1778}1779def BarriernXSAsmOperand : AsmOperandClass {1780 let Name = "BarriernXS";1781 let ParserMethod = "tryParseBarriernXSOperand";1782}1783def barrier_nxs_op : Operand<i32> {1784 let PrintMethod = "printBarriernXSOption";1785 let ParserMatchClass = BarriernXSAsmOperand;1786}1787class CRmSystemI<Operand crmtype, bits<3> opc, string asm,1788 list<dag> pattern = []>1789 : SimpleSystemI<0, (ins crmtype:$CRm), asm, "\t$CRm", pattern>,1790 Sched<[WriteBarrier]> {1791 bits<4> CRm;1792 let Inst{20-12} = 0b000110011;1793 let Inst{11-8} = CRm;1794 let Inst{7-5} = opc;1795}1796 1797class SystemNoOperands<bits<3> op2, string asm, list<dag> pattern = []>1798 : SimpleSystemI<0, (ins), asm, "", pattern>,1799 Sched<[WriteHint]> {1800 bits<4> CRm;1801 let CRm = 0b0011;1802 let Inst{31-12} = 0b11010101000000110010;1803 let Inst{11-8} = CRm;1804 let Inst{7-5} = op2;1805 let Inst{4-0} = 0b11111;1806}1807 1808// MRS/MSR system instructions. These have different operand classes because1809// a different subset of registers can be accessed through each instruction.1810def MRSSystemRegisterOperand : AsmOperandClass {1811 let Name = "MRSSystemRegister";1812 let ParserMethod = "tryParseSysReg";1813 let DiagnosticType = "MRS";1814}1815// concatenation of op0, op1, CRn, CRm, op2. 16-bit immediate.1816def mrs_sysreg_op : Operand<i32> {1817 let ParserMatchClass = MRSSystemRegisterOperand;1818 let DecoderMethod = "DecodeMRSSystemRegister";1819 let PrintMethod = "printMRSSystemRegister";1820}1821 1822def MSRSystemRegisterOperand : AsmOperandClass {1823 let Name = "MSRSystemRegister";1824 let ParserMethod = "tryParseSysReg";1825 let DiagnosticType = "MSR";1826}1827def msr_sysreg_op : Operand<i32> {1828 let ParserMatchClass = MSRSystemRegisterOperand;1829 let DecoderMethod = "DecodeMSRSystemRegister";1830 let PrintMethod = "printMSRSystemRegister";1831}1832 1833def PSBHintOperand : AsmOperandClass {1834 let Name = "PSBHint";1835 let ParserMethod = "tryParsePSBHint";1836}1837def psbhint_op : Operand<i32> {1838 let ParserMatchClass = PSBHintOperand;1839 let PrintMethod = "printPSBHintOp";1840 let MCOperandPredicate = [{1841 // Check, if operand is valid, to fix exhaustive aliasing in disassembly.1842 // "psb" is an alias to "hint" only for certain values of CRm:Op2 fields.1843 if (!MCOp.isImm())1844 return false;1845 return AArch64PSBHint::lookupPSBByEncoding(MCOp.getImm()) != nullptr;1846 }];1847}1848 1849def BTIHintOperand : AsmOperandClass {1850 let Name = "BTIHint";1851 let ParserMethod = "tryParseBTIHint";1852}1853def btihint_op : Operand<i32> {1854 let ParserMatchClass = BTIHintOperand;1855 let PrintMethod = "printBTIHintOp";1856 let MCOperandPredicate = [{1857 // "bti" is an alias to "hint" only for certain values of CRm:Op2 fields.1858 if (!MCOp.isImm())1859 return false;1860 return AArch64BTIHint::lookupBTIByEncoding(MCOp.getImm() ^ 32) != nullptr;1861 }];1862}1863 1864def CMHPriorityHintOperand : AsmOperandClass {1865 let Name = "CMHPriorityHint";1866 let ParserMethod = "tryParseCMHPriorityHint";1867}1868 1869def CMHPriorityHint_op : Operand<i32> {1870 let ParserMatchClass = CMHPriorityHintOperand;1871 let PrintMethod = "printCMHPriorityHintOp";1872 let MCOperandPredicate = [{1873 if (!MCOp.isImm())1874 return false;1875 return AArch64CMHPriorityHint::lookupCMHPriorityHintByEncoding(MCOp.getImm()) != nullptr;1876 }];1877}1878 1879def TIndexHintOperand : AsmOperandClass {1880 let Name = "TIndexHint";1881 let ParserMethod = "tryParseTIndexHint";1882}1883 1884def TIndexhint_op : Operand<i32> {1885 let ParserMatchClass = TIndexHintOperand;1886 let PrintMethod = "printTIndexHintOp";1887 let MCOperandPredicate = [{1888 if (!MCOp.isImm())1889 return false;1890 return AArch64TIndexHint::lookupTIndexByEncoding(MCOp.getImm()) != nullptr;1891 }];1892}1893 1894class MRSI : RtSystemI<1, (outs GPR64:$Rt), (ins mrs_sysreg_op:$systemreg),1895 "mrs", "\t$Rt, $systemreg"> {1896 bits<16> systemreg;1897 let Inst{20-5} = systemreg;1898 let DecoderNamespace = "Fallback";1899 // The MRS is set as a NZCV setting instruction. Not all MRS instructions1900 // require doing this. The alternative was to explicitly model each one, but1901 // it feels like it is unnecessary because it seems there are no negative1902 // consequences setting these flags for all.1903 let Defs = [NZCV];1904}1905 1906// FIXME: Some of these def NZCV, others don't. Best way to model that?1907// Explicitly modeling each of the system register as a register class1908// would do it, but feels like overkill at this point.1909class MSRI : RtSystemI<0, (outs), (ins msr_sysreg_op:$systemreg, GPR64:$Rt),1910 "msr", "\t$systemreg, $Rt"> {1911 bits<16> systemreg;1912 let Inst{20-5} = systemreg;1913 let DecoderNamespace = "Fallback";1914}1915 1916def SystemPStateFieldWithImm0_15Operand : AsmOperandClass {1917 let Name = "SystemPStateFieldWithImm0_15";1918 let ParserMethod = "tryParseSysReg";1919}1920def pstatefield4_op : Operand<i32> {1921 let ParserMatchClass = SystemPStateFieldWithImm0_15Operand;1922 let PrintMethod = "printSystemPStateField";1923 let MCOperandPredicate = [{1924 if (!MCOp.isImm())1925 return false;1926 return AArch64SVCR::lookupPStateImm0_15ByEncoding(MCOp.getImm()) != nullptr;1927 }];1928}1929 1930// Instructions to modify PSTATE, no input reg1931let Defs = [NZCV] in1932class PstateWriteSimple<dag iops, string asm, string operands>1933 : SimpleSystemI<0, iops, asm, operands> {1934 1935 let Inst{20-19} = 0b00;1936 let Inst{15-12} = 0b0100;1937}1938 1939class MSRpstateImm0_151940 : PstateWriteSimple<(ins pstatefield4_op:$pstatefield, imm0_15:$imm), "msr",1941 "\t$pstatefield, $imm">,1942 Sched<[WriteSys]> {1943 1944 bits<6> pstatefield;1945 bits<4> imm;1946 let Inst{18-16} = pstatefield{5-3};1947 let Inst{11-8} = imm;1948 let Inst{7-5} = pstatefield{2-0};1949 1950 let DecoderMethod = "DecodeSystemPStateImm0_15Instruction";1951 // MSRpstateI aliases with MSRI. When the MSRpstateI decoder method returns1952 // Fail the decoder should attempt to decode the instruction as MSRI.1953 let hasCompleteDecoder = false;1954}1955 1956def SystemPStateFieldWithImm0_1Operand : AsmOperandClass {1957 let Name = "SystemPStateFieldWithImm0_1";1958 let ParserMethod = "tryParseSysReg";1959}1960def pstatefield1_op : Operand<i32> {1961 let ParserMatchClass = SystemPStateFieldWithImm0_1Operand;1962 let PrintMethod = "printSystemPStateField";1963 let MCOperandPredicate = [{1964 if (!MCOp.isImm())1965 return false;1966 return AArch64SVCR::lookupPStateImm0_1ByEncoding(MCOp.getImm()) != nullptr;1967 }];1968}1969 1970class MSRpstateImm0_11971 : PstateWriteSimple<(ins pstatefield1_op:$pstatefield, imm0_1:$imm), "msr",1972 "\t$pstatefield, $imm">,1973 Sched<[WriteSys]> {1974 1975 bits<9> pstatefield;1976 bit imm;1977 let Inst{18-16} = pstatefield{5-3};1978 let Inst{11-9} = pstatefield{8-6};1979 let Inst{8} = imm;1980 let Inst{7-5} = pstatefield{2-0};1981 1982 let DecoderMethod = "DecodeSystemPStateImm0_1Instruction";1983 // MSRpstateI aliases with MSRI. When the MSRpstateI decoder method returns1984 // Fail the decoder should attempt to decode the instruction as MSRI.1985 let hasCompleteDecoder = false;1986 let DecoderNamespace = "Fallback";1987}1988 1989// SYS and SYSL generic system instructions.1990def SysCRAsmOperand : AsmOperandClass {1991 let Name = "SysCR";1992 let ParserMethod = "tryParseSysCROperand";1993}1994 1995def sys_cr_op : Operand<i32> {1996 let PrintMethod = "printSysCROperand";1997 let ParserMatchClass = SysCRAsmOperand;1998}1999 2000class SystemXtI<bit L, string asm>2001 : RtSystemI<L, (outs),2002 (ins imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2, GPR64:$Rt),2003 asm, "\t$op1, $Cn, $Cm, $op2, $Rt"> {2004 bits<3> op1;2005 bits<4> Cn;2006 bits<4> Cm;2007 bits<3> op2;2008 let Inst{20-19} = 0b01;2009 let Inst{18-16} = op1;2010 let Inst{15-12} = Cn;2011 let Inst{11-8} = Cm;2012 let Inst{7-5} = op2;2013}2014 2015class SystemLXtI<bit L, string asm>2016 : RtSystemI<L, (outs),2017 (ins GPR64:$Rt, imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2),2018 asm, "\t$Rt, $op1, $Cn, $Cm, $op2"> {2019 bits<3> op1;2020 bits<4> Cn;2021 bits<4> Cm;2022 bits<3> op2;2023 let Inst{20-19} = 0b01;2024 let Inst{18-16} = op1;2025 let Inst{15-12} = Cn;2026 let Inst{11-8} = Cm;2027 let Inst{7-5} = op2;2028}2029 2030def RangePrefetchOperand : AsmOperandClass {2031 let Name = "RangePrefetch";2032 let ParserMethod = "tryParseRPRFMOperand";2033 let PredicateMethod = "isPrefetch";2034 let RenderMethod = "addPrefetchOperands";2035}2036 2037def rprfop : Operand<i32>, TImmLeaf<i32, [{2038 return (((uint32_t)Imm) <= 63);2039 }]> {2040 let PrintMethod = "printRPRFMOperand";2041 let ParserMatchClass = RangePrefetchOperand;2042}2043 2044// Branch (register) instructions:2045//2046// case opc of2047// 0001 blr2048// 0000 br2049// 0101 dret2050// 0100 eret2051// 0010 ret2052// otherwise UNDEFINED2053class BaseBranchReg<bits<4> opc, dag oops, dag iops, string asm,2054 string operands, list<dag> pattern>2055 : I<oops, iops, asm, operands, "", pattern>, Sched<[WriteBrReg]> {2056 let Inst{31-25} = 0b1101011;2057 let Inst{24-21} = opc;2058 let Inst{20-16} = 0b11111;2059 let Inst{15-10} = 0b000000;2060 let Inst{4-0} = 0b00000;2061}2062 2063class BranchReg<bits<4> opc, string asm, list<dag> pattern>2064 : BaseBranchReg<opc, (outs), (ins GPR64:$Rn), asm, "\t$Rn", pattern> {2065 bits<5> Rn;2066 let Inst{9-5} = Rn;2067}2068 2069let mayLoad = 0, mayStore = 0, hasSideEffects = 1, isReturn = 1 in2070class SpecialReturn<bits<4> opc, string asm>2071 : BaseBranchReg<opc, (outs), (ins), asm, "", []> {2072 let Inst{9-5} = 0b11111;2073}2074 2075let mayLoad = 1 in2076class RCPCLoad<bits<2> sz, string asm, RegisterClass RC>2077 : I<(outs RC:$Rt), (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]", "", []>,2078 Sched<[]> {2079 bits<5> Rn;2080 bits<5> Rt;2081 let Inst{31-30} = sz;2082 let Inst{29-10} = 0b11100010111111110000;2083 let Inst{9-5} = Rn;2084 let Inst{4-0} = Rt;2085}2086 2087class AuthBase<bits<1> M, dag oops, dag iops, string asm, string operands,2088 list<dag> pattern>2089 : I<oops, iops, asm, operands, "", pattern>, Sched<[]> {2090 let isAuthenticated = 1;2091 let Inst{31-25} = 0b1101011;2092 let Inst{20-11} = 0b1111100001;2093 let Inst{10} = M;2094 let Inst{4-0} = 0b11111;2095}2096 2097class AuthBranchTwoOperands<bits<1> op, bits<1> M, string asm>2098 : AuthBase<M, (outs), (ins GPR64:$Rn, GPR64sp:$Rm), asm, "\t$Rn, $Rm", []> {2099 bits<5> Rn;2100 bits<5> Rm;2101 let Inst{24-22} = 0b100;2102 let Inst{21} = op;2103 let Inst{9-5} = Rn;2104 let Inst{4-0} = Rm;2105}2106 2107class AuthOneOperand<bits<3> opc, bits<1> M, string asm>2108 : AuthBase<M, (outs), (ins GPR64:$Rn), asm, "\t$Rn", []> {2109 bits<5> Rn;2110 let Inst{24} = 0;2111 let Inst{23-21} = opc;2112 let Inst{9-5} = Rn;2113}2114 2115let Uses = [LR,SP] in2116class AuthReturn<bits<3> op, bits<1> M, string asm>2117 : AuthBase<M, (outs), (ins), asm, "", []> {2118 let Inst{24} = 0;2119 let Inst{23-21} = op;2120 let Inst{9-0} = 0b1111111111;2121}2122 2123let mayLoad = 1 in2124class BaseAuthLoad<bit M, bit W, dag oops, dag iops, string asm,2125 string operands, string cstr>2126 : I<oops, iops, asm, operands, cstr, []>, Sched<[]> {2127 bits<10> offset;2128 bits<5> Rn;2129 bits<5> Rt;2130 let isAuthenticated = 1;2131 let Inst{31-24} = 0b11111000;2132 let Inst{23} = M;2133 let Inst{22} = offset{9};2134 let Inst{21} = 1;2135 let Inst{20-12} = offset{8-0};2136 let Inst{11} = W;2137 let Inst{10} = 1;2138 let Inst{9-5} = Rn;2139 let Inst{4-0} = Rt;2140 2141 let DecoderMethod = "DecodeAuthLoadInstruction";2142}2143 2144multiclass AuthLoad<bit M, string asm, Operand opr> {2145 def indexed : BaseAuthLoad<M, 0, (outs GPR64:$Rt),2146 (ins GPR64sp:$Rn, opr:$offset),2147 asm, "\t$Rt, [$Rn, $offset]", "">;2148 def writeback : BaseAuthLoad<M, 1, (outs GPR64sp:$wback, GPR64:$Rt),2149 (ins GPR64sp:$Rn, opr:$offset),2150 asm, "\t$Rt, [$Rn, $offset]!",2151 "$Rn = $wback,@earlyclobber $wback">;2152 2153 def : InstAlias<asm # "\t$Rt, [$Rn]",2154 (!cast<Instruction>(NAME # "indexed") GPR64:$Rt, GPR64sp:$Rn, 0)>;2155 2156 def : InstAlias<asm # "\t$Rt, [$wback]!",2157 (!cast<Instruction>(NAME # "writeback") GPR64sp:$wback, GPR64:$Rt, 0), 0>;2158}2159 2160//---2161// Conditional branch instruction.2162//---2163 2164// Condition code.2165// 4-bit immediate. Pretty-printed as <cc>2166def ccode : Operand<i32> {2167 let PrintMethod = "printCondCode";2168 let ParserMatchClass = CondCode;2169}2170def inv_ccode : Operand<i32> {2171 // AL and NV are invalid in the aliases which use inv_ccode2172 let PrintMethod = "printInverseCondCode";2173 let ParserMatchClass = CondCode;2174 let MCOperandPredicate = [{2175 return MCOp.isImm() &&2176 MCOp.getImm() != AArch64CC::AL &&2177 MCOp.getImm() != AArch64CC::NV;2178 }];2179}2180 2181// Conditional branch target. 19-bit immediate. The low two bits of the target2182// offset are implied zero and so are not part of the immediate.2183def am_brcond : Operand<OtherVT> {2184 let EncoderMethod = "getCondBranchTargetOpValue";2185 let DecoderMethod = "DecodePCRelLabel19";2186 let PrintMethod = "printAlignedLabel";2187 let ParserMatchClass = PCRelLabel19Operand;2188 let OperandType = "OPERAND_PCREL";2189}2190 2191// Conditional branch target. 9-bit immediate. The low two bits of the target2192// offset are implied zero and so are not part of the immediate.2193def am_brcmpcond : Operand<OtherVT> {2194 let EncoderMethod = "getCondCompBranchTargetOpValue";2195 let DecoderMethod = "DecodePCRelLabel9";2196 let PrintMethod = "printAlignedLabel";2197 let ParserMatchClass = PCRelLabel9Operand;2198 let OperandType = "OPERAND_PCREL";2199}2200 2201 2202class BranchCond<bit bit4, string mnemonic>2203 : I<(outs), (ins ccode:$cond, am_brcond:$target),2204 mnemonic, ".$cond\t$target", "",2205 [(AArch64brcond bb:$target, imm:$cond, NZCV)]>, Sched<[WriteBr]> {2206 let isBranch = 1;2207 let isTerminator = 1;2208 let Uses = [NZCV];2209 2210 bits<4> cond;2211 bits<19> target;2212 let Inst{31-24} = 0b01010100;2213 let Inst{23-5} = target;2214 let Inst{4} = bit4;2215 let Inst{3-0} = cond;2216}2217 2218//---2219// Compare-and-branch instructions.2220//---2221class BaseCmpBranch<RegisterClass regtype, bit op, string asm, SDNode node>2222 : I<(outs), (ins regtype:$Rt, am_brcond:$target),2223 asm, "\t$Rt, $target", "",2224 [(node regtype:$Rt, bb:$target)]>,2225 Sched<[WriteBr]> {2226 let isBranch = 1;2227 let isTerminator = 1;2228 2229 bits<5> Rt;2230 bits<19> target;2231 let Inst{30-25} = 0b011010;2232 let Inst{24} = op;2233 let Inst{23-5} = target;2234 let Inst{4-0} = Rt;2235}2236 2237multiclass CmpBranch<bit op, string asm, SDNode node> {2238 def W : BaseCmpBranch<GPR32, op, asm, node> {2239 let Inst{31} = 0;2240 }2241 def X : BaseCmpBranch<GPR64, op, asm, node> {2242 let Inst{31} = 1;2243 }2244}2245 2246//---2247// Test-bit-and-branch instructions.2248//---2249// Test-and-branch target. 14-bit sign-extended immediate. The low two bits of2250// the target offset are implied zero and so are not part of the immediate.2251def am_tbrcond : Operand<OtherVT> {2252 let EncoderMethod = "getTestBranchTargetOpValue";2253 let PrintMethod = "printAlignedLabel";2254 let ParserMatchClass = BranchTarget14Operand;2255 let OperandType = "OPERAND_PCREL";2256}2257 2258// AsmOperand classes to emit (or not) special diagnostics2259def TBZImm0_31Operand : AsmOperandClass {2260 let Name = "TBZImm0_31";2261 let PredicateMethod = "isImmInRange<0,31>";2262 let RenderMethod = "addImmOperands";2263}2264def TBZImm32_63Operand : AsmOperandClass {2265 let Name = "Imm32_63";2266 let PredicateMethod = "isImmInRange<32,63>";2267 let DiagnosticType = "InvalidImm0_63";2268 let RenderMethod = "addImmOperands";2269}2270 2271class tbz_imm0_31<AsmOperandClass matcher> : Operand<i64>, ImmLeaf<i64, [{2272 return (((uint32_t)Imm) < 32);2273}]> {2274 let ParserMatchClass = matcher;2275}2276 2277def tbz_imm0_31_diag : tbz_imm0_31<Imm0_31Operand>;2278def tbz_imm0_31_nodiag : tbz_imm0_31<TBZImm0_31Operand>;2279 2280def tbz_imm32_63 : Operand<i64>, ImmLeaf<i64, [{2281 return (((uint32_t)Imm) > 31) && (((uint32_t)Imm) < 64);2282}]> {2283 let ParserMatchClass = TBZImm32_63Operand;2284}2285 2286class BaseTestBranch<RegisterClass regtype, Operand immtype,2287 bit op, string asm, SDNode node>2288 : I<(outs), (ins regtype:$Rt, immtype:$bit_off, am_tbrcond:$target),2289 asm, "\t$Rt, $bit_off, $target", "",2290 [(node regtype:$Rt, immtype:$bit_off, bb:$target)]>,2291 Sched<[WriteBr]> {2292 let isBranch = 1;2293 let isTerminator = 1;2294 2295 bits<5> Rt;2296 bits<6> bit_off;2297 bits<14> target;2298 2299 let Inst{30-25} = 0b011011;2300 let Inst{24} = op;2301 let Inst{23-19} = bit_off{4-0};2302 let Inst{18-5} = target;2303 let Inst{4-0} = Rt;2304 2305 let DecoderMethod = "DecodeTestAndBranch";2306}2307 2308multiclass TestBranch<bit op, string asm, SDNode node> {2309 def W : BaseTestBranch<GPR32, tbz_imm0_31_diag, op, asm, node> {2310 let Inst{31} = 0;2311 }2312 2313 def X : BaseTestBranch<GPR64, tbz_imm32_63, op, asm, node> {2314 let Inst{31} = 1;2315 }2316 2317 // Alias X-reg with 0-31 imm to W-Reg.2318 def : InstAlias<asm # "\t$Rd, $imm, $target",2319 (!cast<Instruction>(NAME#"W") GPR32as64:$Rd,2320 tbz_imm0_31_nodiag:$imm, am_tbrcond:$target), 0>;2321 def : Pat<(node GPR64:$Rn, tbz_imm0_31_diag:$imm, bb:$target),2322 (!cast<Instruction>(NAME#"W") (EXTRACT_SUBREG GPR64:$Rn, sub_32),2323 tbz_imm0_31_diag:$imm, bb:$target)>;2324}2325 2326//---2327// Unconditional branch (immediate) instructions.2328//---2329def am_b_target : Operand<OtherVT> {2330 let EncoderMethod = "getBranchTargetOpValue";2331 let PrintMethod = "printAlignedLabel";2332 let ParserMatchClass = BranchTarget26Operand;2333 let OperandType = "OPERAND_PCREL";2334}2335def am_bl_target : Operand<i64> {2336 let EncoderMethod = "getBranchTargetOpValue";2337 let PrintMethod = "printAlignedLabel";2338 let ParserMatchClass = BranchTarget26Operand;2339 let OperandType = "OPERAND_PCREL";2340}2341 2342class BImm<bit op, dag iops, string asm, list<dag> pattern>2343 : I<(outs), iops, asm, "\t$addr", "", pattern>, Sched<[WriteBr]> {2344 bits<26> addr;2345 let Inst{31} = op;2346 let Inst{30-26} = 0b00101;2347 let Inst{25-0} = addr;2348 2349 let DecoderMethod = "DecodeUnconditionalBranch";2350 let supportsDeactivationSymbol = true;2351}2352 2353class BranchImm<bit op, string asm, list<dag> pattern>2354 : BImm<op, (ins am_b_target:$addr), asm, pattern>;2355class CallImm<bit op, string asm, list<dag> pattern>2356 : BImm<op, (ins am_bl_target:$addr), asm, pattern>;2357 2358//---2359// Basic one-operand data processing instructions.2360//---2361 2362let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in2363class BaseOneOperandData<bit sf, bit S, bits<5> opc2, bits<6> opc,2364 RegisterClass regtype, string asm,2365 SDPatternOperator node>2366 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "",2367 [(set regtype:$Rd, (node regtype:$Rn))]>,2368 Sched<[WriteI, ReadI]> {2369 bits<5> Rd;2370 bits<5> Rn;2371 2372 let Inst{31} = sf;2373 let Inst{30} = 0b1;2374 let Inst{29} = S;2375 let Inst{28-21} = 0b11010110;2376 let Inst{20-16} = opc2;2377 let Inst{15-10} = opc;2378 let Inst{9-5} = Rn;2379 let Inst{4-0} = Rd;2380}2381 2382let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in2383multiclass OneOperandData<bits<6> opc, string asm,2384 SDPatternOperator node = null_frag> {2385 def Wr : BaseOneOperandData<0b0, 0b0, 0b00000, opc, GPR32, asm, node>;2386 2387 def Xr : BaseOneOperandData<0b1, 0b0, 0b00000, opc, GPR64, asm, node>;2388}2389 2390class OneWRegData<bits<6> opc, string asm, SDPatternOperator node>2391 : BaseOneOperandData<0b0, 0b0, 0b00000, opc, GPR32, asm, node>;2392 2393class OneXRegData<bits<6> opc, string asm, SDPatternOperator node>2394 : BaseOneOperandData<0b1, 0b0, 0b00000, opc, GPR64, asm, node>;2395 2396class SignAuthOneData<bits<3> opcode_prefix, bits<2> opcode, string asm,2397 SDPatternOperator op>2398 : I<(outs GPR64:$dst), (ins GPR64:$Rd, GPR64sp:$Rn), asm, "\t$Rd, $Rn",2399 "$dst = $Rd", [(set GPR64:$dst, (op GPR64:$Rd, opcode, GPR64sp:$Rn))]>,2400 Sched<[WriteI, ReadI]> {2401 bits<5> Rd;2402 bits<5> Rn;2403 let Inst{31-15} = 0b11011010110000010;2404 let Inst{14-12} = opcode_prefix;2405 let Inst{11-10} = opcode;2406 let Inst{9-5} = Rn;2407 let Inst{4-0} = Rd;2408 let supportsDeactivationSymbol = true;2409}2410 2411class SignAuthZero<bits<3> opcode_prefix, bits<2> opcode, string asm,2412 SDPatternOperator op>2413 : I<(outs GPR64:$dst), (ins GPR64:$Rd), asm, "\t$Rd", "$dst = $Rd",2414 [(set GPR64:$dst, (op GPR64:$Rd, opcode, (i64 0)))]>,2415 Sched<[]> {2416 bits<5> Rd;2417 let Inst{31-15} = 0b11011010110000010;2418 let Inst{14-12} = opcode_prefix;2419 let Inst{11-10} = opcode;2420 let Inst{9-5} = 0b11111;2421 let Inst{4-0} = Rd;2422 let supportsDeactivationSymbol = true;2423}2424 2425class SignAuthTwoOperand<bits<4> opc, string asm,2426 SDPatternOperator OpNode>2427 : I<(outs GPR64:$Rd), (ins GPR64:$Rn, GPR64sp:$Rm),2428 asm, "\t$Rd, $Rn, $Rm", "",2429 [(set GPR64:$Rd, (OpNode GPR64:$Rn, GPR64sp:$Rm))]>,2430 Sched<[WriteI, ReadI, ReadI]> {2431 bits<5> Rd;2432 bits<5> Rn;2433 bits<5> Rm;2434 let Inst{31-21} = 0b10011010110;2435 let Inst{20-16} = Rm;2436 let Inst{15-14} = 0b00;2437 let Inst{13-10} = opc;2438 let Inst{9-5} = Rn;2439 let Inst{4-0} = Rd;2440}2441 2442class ClearAuth<bits<1> data, string asm>2443 : I<(outs GPR64:$Rd), (ins GPR64:$Rn), asm, "\t$Rd", "$Rd = $Rn", []>, Sched<[]> {2444 bits<5> Rd;2445 let Inst{31-11} = 0b110110101100000101000;2446 let Inst{10} = data;2447 let Inst{9-5} = 0b11111;2448 let Inst{4-0} = Rd;2449}2450 2451// v9.5-A FEAT_PAuth_LR2452 2453class SignAuthFixedRegs<bits<5> opcode2, bits<6> opcode, string asm>2454 : I<(outs), (ins), asm, "", "", []>,2455 Sched<[WriteI, ReadI]> {2456 let Inst{31} = 0b1; // sf2457 let Inst{30} = 0b1;2458 let Inst{29} = 0b0; // S2459 let Inst{28-21} = 0b11010110;2460 let Inst{20-16} = opcode2;2461 let Inst{15-10} = opcode;2462 let Inst{9-5} = 0b11111; // Rn2463 let Inst{4-0} = 0b11110; // Rd2464}2465 2466def PAuthPCRelLabel16Operand : PCRelLabel<16> {2467 let Name = "PAuthPCRelLabel16";2468 let PredicateMethod = "isPAuthPCRelLabel16Operand";2469}2470def am_pauth_pcrel : Operand<OtherVT> {2471 let EncoderMethod = "getPAuthPCRelOpValue";2472 let DecoderMethod = "DecodePCRelLabel16";2473 let PrintMethod = "printAlignedLabel";2474 let ParserMatchClass = PAuthPCRelLabel16Operand;2475 let OperandType = "OPERAND_PCREL";2476}2477 2478class SignAuthPCRel<bits<2> opc, string asm>2479 : I<(outs), (ins am_pauth_pcrel:$label), asm, "\t$label", "", []>,2480 Sched<[]> {2481 bits<16> label;2482 let Inst{31} = 0b1; // sf2483 let Inst{30-23} = 0b11100111;2484 let Inst{22-21} = opc;2485 let Inst{20-5} = label; // imm2486 let Inst{4-0} = 0b11111; // Rd2487}2488 2489class SignAuthOneReg<bits<5> opcode2, bits<6> opcode, string asm>2490 : I<(outs), (ins GPR64:$Rn), asm, "\t$Rn", "", []>,2491 Sched<[]> {2492 bits<5> Rn;2493 let Inst{31} = 0b1; // sf2494 let Inst{30} = 0b1;2495 let Inst{29} = 0b0; // S2496 let Inst{28-21} = 0b11010110;2497 let Inst{20-16} = opcode2;2498 let Inst{15-10} = opcode;2499 let Inst{9-5} = Rn;2500 let Inst{4-0} = 0b11110; // Rd2501}2502 2503class SignAuthReturnPCRel<bits<3> opc, bits<5> op2, string asm>2504 : I<(outs), (ins am_pauth_pcrel:$label), asm, "\t$label", "", []>,2505 Sched<[WriteAtomic]> {2506 bits<16> label;2507 let Inst{31-24} = 0b01010101;2508 let Inst{23-21} = opc;2509 let Inst{20-5} = label; // imm162510 let Inst{4-0} = op2;2511}2512 2513class SignAuthReturnReg<bits<6> op3, string asm>2514 : I<(outs), (ins GPR64common:$Rm), asm, "\t$Rm", "", []>,2515 Sched<[WriteAtomic]> {2516 bits<5> Rm;2517 let Inst{31-25} = 0b1101011;2518 let Inst{24-21} = 0b0010; // opc2519 let Inst{20-16} = 0b11111; // op22520 let Inst{15-10} = op3;2521 let Inst{9-5} = 0b11111; // Rn2522 let Inst{4-0} = Rm; // op4 (Rm)2523}2524 2525// Base class for the Armv8.4-A 8 and 16-bit flag manipulation instructions2526class BaseFlagManipulation<bit sf, bit sz, dag iops, string asm, string ops>2527 : I<(outs), iops, asm, ops, "", []>,2528 Sched<[WriteI, ReadI, ReadI]> {2529 let Uses = [NZCV];2530 let Defs = [NZCV];2531 bits<5> Rn;2532 let Inst{31} = sf;2533 let Inst{30-15} = 0b0111010000000000;2534 let Inst{14} = sz;2535 let Inst{13-10} = 0b0010;2536 let Inst{9-5} = Rn;2537 let Inst{4-0} = 0b01101;2538}2539 2540class FlagRotate<dag iops, string asm, string ops>2541 : BaseFlagManipulation<0b1, 0b0, iops, asm, ops> {2542 bits<6> imm;2543 bits<4> mask;2544 let Inst{20-15} = imm;2545 let Inst{13-10} = 0b0001;2546 let Inst{4} = 0b0;2547 let Inst{3-0} = mask;2548}2549 2550//---2551// Basic two-operand data processing instructions.2552//---2553class BaseBaseAddSubCarry<bit isSub, RegisterClass regtype, string asm,2554 list<dag> pattern>2555 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),2556 asm, "\t$Rd, $Rn, $Rm", "", pattern>,2557 Sched<[WriteI, ReadI, ReadI]> {2558 let Uses = [NZCV];2559 bits<5> Rd;2560 bits<5> Rn;2561 bits<5> Rm;2562 let Inst{30} = isSub;2563 let Inst{28-21} = 0b11010000;2564 let Inst{20-16} = Rm;2565 let Inst{15-10} = 0;2566 let Inst{9-5} = Rn;2567 let Inst{4-0} = Rd;2568}2569 2570class BaseAddSubCarry<bit isSub, RegisterClass regtype, string asm,2571 SDNode OpNode>2572 : BaseBaseAddSubCarry<isSub, regtype, asm,2573 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV))]>;2574 2575class BaseAddSubCarrySetFlags<bit isSub, RegisterClass regtype, string asm,2576 SDNode OpNode>2577 : BaseBaseAddSubCarry<isSub, regtype, asm,2578 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm, NZCV))]> {2579 let Defs = [NZCV];2580}2581 2582multiclass AddSubCarry<bit isSub, string asm, string asm_setflags,2583 SDNode OpNode, SDNode OpNode_setflags> {2584 def Wr : BaseAddSubCarry<isSub, GPR32, asm, OpNode> {2585 let Inst{31} = 0;2586 let Inst{29} = 0;2587 }2588 def Xr : BaseAddSubCarry<isSub, GPR64, asm, OpNode> {2589 let Inst{31} = 1;2590 let Inst{29} = 0;2591 }2592 2593 // Sets flags.2594 def SWr : BaseAddSubCarrySetFlags<isSub, GPR32, asm_setflags,2595 OpNode_setflags> {2596 let Inst{31} = 0;2597 let Inst{29} = 1;2598 }2599 def SXr : BaseAddSubCarrySetFlags<isSub, GPR64, asm_setflags,2600 OpNode_setflags> {2601 let Inst{31} = 1;2602 let Inst{29} = 1;2603 }2604}2605 2606class BaseTwoOperandRegReg<bit sf, bit S, bits<6> opc, RegisterClass regtype,2607 string asm, SDPatternOperator OpNode,2608 RegisterClass in1regtype = regtype,2609 RegisterClass in2regtype = regtype>2610 : I<(outs regtype:$Rd), (ins in1regtype:$Rn, in2regtype:$Rm),2611 asm, "\t$Rd, $Rn, $Rm", "",2612 [(set regtype:$Rd, (OpNode in1regtype:$Rn, in2regtype:$Rm))]> {2613 bits<5> Rd;2614 bits<5> Rn;2615 bits<5> Rm;2616 let Inst{31} = sf;2617 let Inst{30} = 0b0;2618 let Inst{29} = S;2619 let Inst{28-21} = 0b11010110;2620 let Inst{20-16} = Rm;2621 let Inst{15-10} = opc;2622 let Inst{9-5} = Rn;2623 let Inst{4-0} = Rd;2624}2625 2626class BaseDiv<bit size, bit isSigned, RegisterClass regtype, string asm,2627 SDPatternOperator OpNode>2628 : BaseTwoOperandRegReg<size, 0b0, {0,0,0,0,1,?}, regtype, asm, OpNode> {2629 let Inst{10} = isSigned;2630}2631 2632multiclass Div<bit isSigned, string asm, SDPatternOperator OpNode> {2633 def Wr : BaseDiv<0b0, isSigned, GPR32, asm, OpNode>,2634 Sched<[WriteID32, ReadID, ReadID]>;2635 2636 def Xr : BaseDiv<0b1, isSigned, GPR64, asm, OpNode>,2637 Sched<[WriteID64, ReadID, ReadID]>;2638}2639 2640class BaseShift<bit size, bits<2> shift_type, RegisterClass regtype, string asm,2641 SDPatternOperator OpNode = null_frag>2642 : BaseTwoOperandRegReg<size, 0b0, {0,0,1,0,?,?}, regtype, asm, OpNode>,2643 Sched<[WriteIS, ReadI]> {2644 let Inst{11-10} = shift_type;2645}2646 2647multiclass Shift<bits<2> shift_type, string asm, SDNode OpNode> {2648 def Wr : BaseShift<0b0, shift_type, GPR32, asm>;2649 2650 def Xr : BaseShift<0b1, shift_type, GPR64, asm, OpNode>;2651 2652 def : Pat<(i32 (OpNode GPR32:$Rn, i64:$Rm)),2653 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn,2654 (EXTRACT_SUBREG GPR64:$Rm, sub_32))>;2655 2656 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (zext GPR32:$Rm)))),2657 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>;2658 2659 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (anyext GPR32:$Rm)))),2660 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>;2661 2662 def : Pat<(i32 (OpNode GPR32:$Rn, (i64 (sext GPR32:$Rm)))),2663 (!cast<Instruction>(NAME # "Wr") GPR32:$Rn, GPR32:$Rm)>;2664 2665 def : Pat<(i64 (OpNode GPR64:$Rn, (i64 (sext GPR32:$Rm)))),2666 (!cast<Instruction>(NAME # "Xr") GPR64:$Rn,2667 (SUBREG_TO_REG (i32 0), GPR32:$Rm, sub_32))>;2668 2669 def : Pat<(i64 (OpNode GPR64:$Rn, (i64 (zext GPR32:$Rm)))),2670 (!cast<Instruction>(NAME # "Xr") GPR64:$Rn,2671 (SUBREG_TO_REG (i32 0), GPR32:$Rm, sub_32))>;2672}2673 2674class ShiftAlias<string asm, Instruction inst, RegisterClass regtype>2675 : InstAlias<asm#"\t$dst, $src1, $src2",2676 (inst regtype:$dst, regtype:$src1, regtype:$src2), 0>;2677 2678class BaseMulAccum<bit isSub, bits<3> opc, RegisterClass multype,2679 RegisterClass addtype, string asm,2680 list<dag> pattern>2681 : I<(outs addtype:$Rd), (ins multype:$Rn, multype:$Rm, addtype:$Ra),2682 asm, "\t$Rd, $Rn, $Rm, $Ra", "", pattern> {2683 bits<5> Rd;2684 bits<5> Rn;2685 bits<5> Rm;2686 bits<5> Ra;2687 let Inst{30-24} = 0b0011011;2688 let Inst{23-21} = opc;2689 let Inst{20-16} = Rm;2690 let Inst{15} = isSub;2691 let Inst{14-10} = Ra;2692 let Inst{9-5} = Rn;2693 let Inst{4-0} = Rd;2694}2695 2696multiclass MulAccum<bit isSub, string asm> {2697 // MADD/MSUB generation is decided by MachineCombiner.cpp2698 def Wrrr : BaseMulAccum<isSub, 0b000, GPR32, GPR32, asm, []>,2699 Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> {2700 let Inst{31} = 0;2701 }2702 2703 def Xrrr : BaseMulAccum<isSub, 0b000, GPR64, GPR64, asm, []>,2704 Sched<[WriteIM64, ReadIM, ReadIM, ReadIMA]> {2705 let Inst{31} = 1;2706 }2707}2708 2709class WideMulAccum<bit isSub, bits<3> opc, string asm,2710 SDNode AccNode, SDNode ExtNode>2711 : BaseMulAccum<isSub, opc, GPR32, GPR64, asm,2712 [(set GPR64:$Rd, (AccNode GPR64:$Ra,2713 (mul (ExtNode GPR32:$Rn), (ExtNode GPR32:$Rm))))]>,2714 Sched<[WriteIM32, ReadIM, ReadIM, ReadIMA]> {2715 let Inst{31} = 1;2716}2717 2718class MulHi<bits<3> opc, string asm, SDNode OpNode>2719 : I<(outs GPR64:$Rd), (ins GPR64:$Rn, GPR64:$Rm),2720 asm, "\t$Rd, $Rn, $Rm", "",2721 [(set GPR64:$Rd, (OpNode GPR64:$Rn, GPR64:$Rm))]>,2722 Sched<[WriteIM64, ReadIM, ReadIM]> {2723 bits<5> Rd;2724 bits<5> Rn;2725 bits<5> Rm;2726 let Inst{31-24} = 0b10011011;2727 let Inst{23-21} = opc;2728 let Inst{20-16} = Rm;2729 let Inst{15} = 0;2730 let Inst{14-10} = 0b11111;2731 let Unpredictable{14-10} = 0b11111;2732 let Inst{9-5} = Rn;2733 let Inst{4-0} = Rd;2734 2735 // The Ra field of SMULH and UMULH is unused: it should be assembled as 312736 // (i.e. all bits 1) but is ignored by the processor.2737 let PostEncoderMethod = "fixMulHigh";2738}2739 2740class MulAccumWAlias<string asm, Instruction inst>2741 : InstAlias<asm#"\t$dst, $src1, $src2",2742 (inst GPR32:$dst, GPR32:$src1, GPR32:$src2, WZR)>;2743class MulAccumXAlias<string asm, Instruction inst>2744 : InstAlias<asm#"\t$dst, $src1, $src2",2745 (inst GPR64:$dst, GPR64:$src1, GPR64:$src2, XZR)>;2746class WideMulAccumAlias<string asm, Instruction inst>2747 : InstAlias<asm#"\t$dst, $src1, $src2",2748 (inst GPR64:$dst, GPR32:$src1, GPR32:$src2, XZR)>;2749 2750class BaseCRC32<bit sf, bits<2> sz, bit C, RegisterClass StreamReg,2751 SDPatternOperator OpNode, string asm>2752 : I<(outs GPR32:$Rd), (ins GPR32:$Rn, StreamReg:$Rm),2753 asm, "\t$Rd, $Rn, $Rm", "",2754 [(set GPR32:$Rd, (OpNode GPR32:$Rn, StreamReg:$Rm))]>,2755 Sched<[WriteISReg, ReadI, ReadISReg]> {2756 bits<5> Rd;2757 bits<5> Rn;2758 bits<5> Rm;2759 2760 let Inst{31} = sf;2761 let Inst{30-21} = 0b0011010110;2762 let Inst{20-16} = Rm;2763 let Inst{15-13} = 0b010;2764 let Inst{12} = C;2765 let Inst{11-10} = sz;2766 let Inst{9-5} = Rn;2767 let Inst{4-0} = Rd;2768 let Predicates = [HasCRC];2769}2770 2771//---2772// Address generation.2773//---2774 2775class ADRI<bit page, string asm, Operand adr, list<dag> pattern>2776 : I<(outs GPR64:$Xd), (ins adr:$label), asm, "\t$Xd, $label", "",2777 pattern>,2778 Sched<[WriteI]> {2779 bits<5> Xd;2780 bits<21> label;2781 let Inst{31} = page;2782 let Inst{30-29} = label{1-0};2783 let Inst{28-24} = 0b10000;2784 let Inst{23-5} = label{20-2};2785 let Inst{4-0} = Xd;2786 2787 let DecoderMethod = "DecodeAdrInstruction";2788}2789 2790//---2791// Move immediate.2792//---2793 2794def movimm32_imm : Operand<i32> {2795 let ParserMatchClass = AsmImmRange<0, 65535>;2796 let EncoderMethod = "getMoveWideImmOpValue";2797 let PrintMethod = "printImm";2798}2799def movimm32_shift : Operand<i32> {2800 let PrintMethod = "printShifter";2801 let ParserMatchClass = MovImm32ShifterOperand;2802}2803def movimm64_shift : Operand<i32> {2804 let PrintMethod = "printShifter";2805 let ParserMatchClass = MovImm64ShifterOperand;2806}2807 2808let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in2809class BaseMoveImmediate<bits<2> opc, RegisterClass regtype, Operand shifter,2810 string asm>2811 : I<(outs regtype:$Rd), (ins movimm32_imm:$imm, shifter:$shift),2812 asm, "\t$Rd, $imm$shift", "", []>,2813 Sched<[WriteImm]> {2814 bits<5> Rd;2815 bits<16> imm;2816 bits<6> shift;2817 let Inst{30-29} = opc;2818 let Inst{28-23} = 0b100101;2819 let Inst{22-21} = shift{5-4};2820 let Inst{20-5} = imm;2821 let Inst{4-0} = Rd;2822 2823 let DecoderMethod = "DecodeMoveImmInstruction";2824}2825 2826multiclass MoveImmediate<bits<2> opc, string asm> {2827 def Wi : BaseMoveImmediate<opc, GPR32, movimm32_shift, asm> {2828 let Inst{31} = 0;2829 }2830 2831 def Xi : BaseMoveImmediate<opc, GPR64, movimm64_shift, asm> {2832 let Inst{31} = 1;2833 }2834}2835 2836let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in2837class BaseInsertImmediate<bits<2> opc, RegisterClass regtype, Operand shifter,2838 string asm>2839 : I<(outs regtype:$Rd),2840 (ins regtype:$src, movimm32_imm:$imm, shifter:$shift),2841 asm, "\t$Rd, $imm$shift", "$src = $Rd", []>,2842 Sched<[WriteI, ReadI]> {2843 bits<5> Rd;2844 bits<16> imm;2845 bits<6> shift;2846 let Inst{30-29} = opc;2847 let Inst{28-23} = 0b100101;2848 let Inst{22-21} = shift{5-4};2849 let Inst{20-5} = imm;2850 let Inst{4-0} = Rd;2851 2852 let DecoderMethod = "DecodeMoveImmInstruction";2853}2854 2855multiclass InsertImmediate<bits<2> opc, string asm> {2856 def Wi : BaseInsertImmediate<opc, GPR32, movimm32_shift, asm> {2857 let Inst{31} = 0;2858 }2859 2860 def Xi : BaseInsertImmediate<opc, GPR64, movimm64_shift, asm> {2861 let Inst{31} = 1;2862 }2863}2864 2865//---2866// Add/Subtract2867//---2868 2869class BaseAddSubImm<bit isSub, bit setFlags, RegisterClass dstRegtype,2870 string asm_inst, string asm_ops,2871 dag inputs, dag pattern>2872 : I<(outs dstRegtype:$Rd), inputs, asm_inst, asm_ops, "", [pattern]>,2873 Sched<[WriteI, ReadI]> {2874 bits<5> Rd;2875 bits<5> Rn;2876 let Inst{30} = isSub;2877 let Inst{29} = setFlags;2878 let Inst{28-24} = 0b10001;2879 let Inst{9-5} = Rn;2880 let Inst{4-0} = Rd;2881}2882 2883class AddSubImmShift<bit isSub, bit setFlags, RegisterClass dstRegtype,2884 RegisterClass srcRegtype, addsub_shifted_imm immtype,2885 string asm_inst, SDPatternOperator OpNode>2886 : BaseAddSubImm<isSub, setFlags, dstRegtype, asm_inst, "\t$Rd, $Rn, $imm",2887 (ins srcRegtype:$Rn, immtype:$imm),2888 (set dstRegtype:$Rd, (OpNode srcRegtype:$Rn, immtype:$imm))> {2889 bits<14> imm;2890 let Inst{23-22} = imm{13-12}; // '00' => lsl #0, '01' => lsl #122891 let Inst{21-10} = imm{11-0};2892 let DecoderMethod = "DecodeAddSubImmShift";2893 let hasPostISelHook = 1;2894}2895 2896class BaseAddSubRegPseudo<RegisterClass regtype,2897 SDPatternOperator OpNode>2898 : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),2899 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>,2900 Sched<[WriteI, ReadI, ReadI]>;2901 2902class BaseAddSubSReg<bit isSub, bit setFlags, RegisterClass regtype,2903 arith_shifted_reg shifted_regtype, string asm,2904 SDPatternOperator OpNode>2905 : I<(outs regtype:$Rd), (ins regtype:$Rn, (shifted_regtype $Rm, $shift):$Rm_and_shift),2906 asm, "\t$Rd, $Rn, $Rm_and_shift", "",2907 [(set regtype:$Rd, (OpNode regtype:$Rn, shifted_regtype:$Rm_and_shift))]>,2908 Sched<[WriteISReg, ReadI, ReadISReg]> {2909 bits<5> Rd;2910 bits<5> Rn;2911 bits<5> Rm;2912 bits<8> shift;2913 let Inst{30} = isSub;2914 let Inst{29} = setFlags;2915 let Inst{28-24} = 0b01011;2916 let Inst{23-22} = shift{7-6};2917 let Inst{21} = 0;2918 let Inst{20-16} = Rm;2919 let Inst{15-10} = shift{5-0};2920 let Inst{9-5} = Rn;2921 let Inst{4-0} = Rd;2922 2923 let DecoderMethod = "DecodeThreeAddrSRegInstruction";2924}2925 2926class BaseAddSubEReg<bit isSub, bit setFlags, RegisterClass dstRegtype,2927 RegisterClass src1Regtype, Operand src2Regtype,2928 string asm, SDPatternOperator OpNode>2929 : I<(outs dstRegtype:$Rd),2930 (ins src1Regtype:$Rn, (src2Regtype $Rm, $extend):$Rm_and_extend),2931 asm, "\t$Rd, $Rn, $Rm_and_extend", "",2932 [(set dstRegtype:$Rd, (OpNode src1Regtype:$Rn, src2Regtype:$Rm_and_extend))]>,2933 Sched<[WriteIEReg, ReadI, ReadIEReg]> {2934 bits<5> Rd;2935 bits<5> Rn;2936 bits<5> Rm;2937 bits<6> extend;2938 let Inst{30} = isSub;2939 let Inst{29} = setFlags;2940 let Inst{28-24} = 0b01011;2941 let Inst{23-21} = 0b001;2942 let Inst{20-16} = Rm;2943 let Inst{15-13} = extend{5-3};2944 let Inst{12-10} = extend{2-0};2945 let Inst{9-5} = Rn;2946 let Inst{4-0} = Rd;2947 2948 let DecoderMethod = "DecodeAddSubERegInstruction";2949}2950 2951let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in2952class BaseAddSubEReg64<bit isSub, bit setFlags, RegisterClass dstRegtype,2953 RegisterClass src1Regtype, RegisterClass src2Regtype,2954 Operand ext_op, string asm>2955 : I<(outs dstRegtype:$Rd),2956 (ins src1Regtype:$Rn, src2Regtype:$Rm, ext_op:$ext),2957 asm, "\t$Rd, $Rn, $Rm$ext", "", []>,2958 Sched<[WriteIEReg, ReadI, ReadIEReg]> {2959 bits<5> Rd;2960 bits<5> Rn;2961 bits<5> Rm;2962 bits<6> ext;2963 let Inst{30} = isSub;2964 let Inst{29} = setFlags;2965 let Inst{28-24} = 0b01011;2966 let Inst{23-21} = 0b001;2967 let Inst{20-16} = Rm;2968 let Inst{15} = ext{5};2969 let Inst{12-10} = ext{2-0};2970 let Inst{9-5} = Rn;2971 let Inst{4-0} = Rd;2972 2973 let DecoderMethod = "DecodeAddSubERegInstruction";2974}2975 2976// Aliases for register+register add/subtract.2977class AddSubRegAlias<string asm, Instruction inst, RegisterClass dstRegtype,2978 RegisterClass src1Regtype, dag src2>2979 : InstAlias<asm#"\t$dst, $src1, $src2",2980 (inst dstRegtype:$dst, src1Regtype:$src1, src2)>;2981class AddSubRegAlias64<string asm, Instruction inst, RegisterClass dstRegtype,2982 RegisterClass src1Regtype, RegisterClass src2Regtype,2983 int shiftExt>2984 : InstAlias<asm#"\t$dst, $src1, $src2",2985 (inst dstRegtype:$dst, src1Regtype:$src1, src2Regtype:$src2,2986 shiftExt)>;2987 2988multiclass AddSub<bit isSub, string mnemonic, string alias,2989 SDPatternOperator OpNode = null_frag> {2990 let hasSideEffects = 0, isReMaterializable = 1, isAsCheapAsAMove = 1 in {2991 // Add/Subtract immediate2992 // Increase the weight of the immediate variant to try to match it before2993 // the extended register variant.2994 // We used to match the register variant before the immediate when the2995 // register argument could be implicitly zero-extended.2996 let AddedComplexity = 6 in2997 def Wri : AddSubImmShift<isSub, 0, GPR32sp, GPR32sp, addsub_shifted_imm32,2998 mnemonic, OpNode> {2999 let Inst{31} = 0;3000 }3001 let AddedComplexity = 6 in3002 def Xri : AddSubImmShift<isSub, 0, GPR64sp, GPR64sp, addsub_shifted_imm64,3003 mnemonic, OpNode> {3004 let Inst{31} = 1;3005 }3006 3007 // Add/Subtract register - Only used for CodeGen3008 def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>;3009 def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>;3010 3011 // Add/Subtract shifted register3012 def Wrs : BaseAddSubSReg<isSub, 0, GPR32, arith_shifted_reg32, mnemonic,3013 OpNode> {3014 let Inst{31} = 0;3015 }3016 def Xrs : BaseAddSubSReg<isSub, 0, GPR64, arith_shifted_reg64, mnemonic,3017 OpNode> {3018 let Inst{31} = 1;3019 }3020 }3021 3022 // Add/Subtract extended register3023 let AddedComplexity = 1, hasSideEffects = 0 in {3024 def Wrx : BaseAddSubEReg<isSub, 0, GPR32sp, GPR32sp,3025 arith_extended_reg32_i32, mnemonic, OpNode> {3026 let Inst{31} = 0;3027 }3028 def Xrx : BaseAddSubEReg<isSub, 0, GPR64sp, GPR64sp,3029 arith_extended_reg32to64_i64, mnemonic, OpNode> {3030 let Inst{31} = 1;3031 }3032 }3033 3034 def Xrx64 : BaseAddSubEReg64<isSub, 0, GPR64sp, GPR64sp, GPR64,3035 arith_extendlsl64, mnemonic> {3036 // UXTX and SXTX only.3037 let Inst{14-13} = 0b11;3038 let Inst{31} = 1;3039 }3040 3041 // add Rd, Rb, -imm -> sub Rd, Rn, imm3042 def : InstSubst<alias#"\t$Rd, $Rn, $imm",3043 (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32sp:$Rn,3044 addsub_shifted_imm32_neg:$imm), 0>;3045 def : InstSubst<alias#"\t$Rd, $Rn, $imm",3046 (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64sp:$Rn,3047 addsub_shifted_imm64_neg:$imm), 0>;3048 3049 // Register/register aliases with no shift when SP is not used.3050 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"),3051 GPR32, GPR32, (arith_shifted_reg32 GPR32:$src2, 0)>;3052 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"),3053 GPR64, GPR64, (arith_shifted_reg64 GPR64:$src2, 0)>;3054 3055 // Register/register aliases with no shift when either the destination or3056 // first source register is SP.3057 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"),3058 GPR32sponly, GPR32sp,3059 (arith_extended_reg32_i32 GPR32:$src2, 16)>; // UXTW #03060 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"),3061 GPR32sp, GPR32sponly,3062 (arith_extended_reg32_i32 GPR32:$src2, 16)>; // UXTW #03063 def : AddSubRegAlias64<mnemonic, !cast<Instruction>(NAME#"Xrx64"),3064 GPR64sponly, GPR64sp, GPR64, 24>; // UXTX #03065 def : AddSubRegAlias64<mnemonic, !cast<Instruction>(NAME#"Xrx64"),3066 GPR64sp, GPR64sponly, GPR64, 24>; // UXTX #03067}3068 3069multiclass AddSubS<bit isSub, string mnemonic, SDNode OpNode, string cmp,3070 string alias, string cmpAlias> {3071 let isCompare = 1, Defs = [NZCV] in {3072 // Add/Subtract immediate3073 def Wri : AddSubImmShift<isSub, 1, GPR32, GPR32sp, addsub_shifted_imm32,3074 mnemonic, OpNode> {3075 let Inst{31} = 0;3076 }3077 def Xri : AddSubImmShift<isSub, 1, GPR64, GPR64sp, addsub_shifted_imm64,3078 mnemonic, OpNode> {3079 let Inst{31} = 1;3080 }3081 3082 // Add/Subtract register3083 def Wrr : BaseAddSubRegPseudo<GPR32, OpNode>;3084 def Xrr : BaseAddSubRegPseudo<GPR64, OpNode>;3085 3086 // Add/Subtract shifted register3087 def Wrs : BaseAddSubSReg<isSub, 1, GPR32, arith_shifted_reg32, mnemonic,3088 OpNode> {3089 let Inst{31} = 0;3090 }3091 def Xrs : BaseAddSubSReg<isSub, 1, GPR64, arith_shifted_reg64, mnemonic,3092 OpNode> {3093 let Inst{31} = 1;3094 }3095 3096 // Add/Subtract extended register3097 let AddedComplexity = 1 in {3098 def Wrx : BaseAddSubEReg<isSub, 1, GPR32, GPR32sp,3099 arith_extended_reg32_i32, mnemonic, OpNode> {3100 let Inst{31} = 0;3101 }3102 def Xrx : BaseAddSubEReg<isSub, 1, GPR64, GPR64sp,3103 arith_extended_reg32_i64, mnemonic, OpNode> {3104 let Inst{31} = 1;3105 }3106 }3107 3108 def Xrx64 : BaseAddSubEReg64<isSub, 1, GPR64, GPR64sp, GPR64,3109 arith_extendlsl64, mnemonic> {3110 // UXTX and SXTX only.3111 let Inst{14-13} = 0b11;3112 let Inst{31} = 1;3113 }3114 } // Defs = [NZCV]3115 3116 // Support negative immediates, e.g. adds Rd, Rn, -imm -> subs Rd, Rn, imm3117 def : InstSubst<alias#"\t$Rd, $Rn, $imm",3118 (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32sp:$Rn,3119 addsub_shifted_imm32_neg:$imm), 0>;3120 def : InstSubst<alias#"\t$Rd, $Rn, $imm",3121 (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64sp:$Rn,3122 addsub_shifted_imm64_neg:$imm), 0>;3123 3124 // Compare aliases3125 def : InstAlias<cmp#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri")3126 WZR, GPR32sp:$src, addsub_shifted_imm32:$imm), 5>;3127 def : InstAlias<cmp#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri")3128 XZR, GPR64sp:$src, addsub_shifted_imm64:$imm), 5>;3129 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Wrx")3130 WZR, GPR32sp:$src1,3131 (arith_extended_reg32_i32 GPR32:$src2, arith_extend:$sh)), 4>;3132 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx")3133 XZR, GPR64sp:$src1,3134 (arith_extended_reg32_i64 GPR32:$src2, arith_extend:$sh)), 4>;3135 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrx64")3136 XZR, GPR64sp:$src1, GPR64:$src2, arith_extendlsl64:$sh), 4>;3137 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Wrs")3138 WZR, GPR32:$src1,3139 (arith_shifted_reg32 GPR32:$src2, arith_shift32:$sh)), 4>;3140 def : InstAlias<cmp#"\t$src1, $src2$sh", (!cast<Instruction>(NAME#"Xrs")3141 XZR, GPR64:$src1,3142 (arith_shifted_reg64 GPR64:$src2, arith_shift64:$sh)), 4>;3143 3144 // Support negative immediates, e.g. cmp Rn, -imm -> cmn Rn, imm3145 def : InstSubst<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Wri")3146 WZR, GPR32sp:$src, addsub_shifted_imm32_neg:$imm), 0>;3147 def : InstSubst<cmpAlias#"\t$src, $imm", (!cast<Instruction>(NAME#"Xri")3148 XZR, GPR64sp:$src, addsub_shifted_imm64_neg:$imm), 0>;3149 3150 // Compare shorthands3151 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Wrs")3152 WZR, GPR32:$src1, (arith_shifted_reg32 GPR32:$src2, 0)), 5>;3153 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Xrs")3154 XZR, GPR64:$src1, (arith_shifted_reg64 GPR64:$src2, 0)), 5>;3155 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Wrx")3156 WZR, GPR32sponly:$src1,3157 (arith_extended_reg32_i32 GPR32:$src2, 16)), 5>;3158 def : InstAlias<cmp#"\t$src1, $src2", (!cast<Instruction>(NAME#"Xrx64")3159 XZR, GPR64sponly:$src1, GPR64:$src2, 24), 5>;3160 3161 // Register/register aliases with no shift when SP is not used.3162 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"),3163 GPR32, GPR32, (arith_shifted_reg32 GPR32:$src2, 0)>;3164 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"),3165 GPR64, GPR64, (arith_shifted_reg64 GPR64:$src2, 0)>;3166 3167 // Register/register aliases with no shift when the first source register3168 // is SP.3169 def : AddSubRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrx"),3170 GPR32, GPR32sponly,3171 (arith_extended_reg32_i32 GPR32:$src2, 16)>; // UXTW #03172 def : AddSubRegAlias64<mnemonic, !cast<Instruction>(NAME#"Xrx64"),3173 GPR64, GPR64sponly, GPR64, 24>; // UXTX #03174}3175 3176class AddSubG<bit isSub, string asm_inst, SDPatternOperator OpNode>3177 : BaseAddSubImm<3178 isSub, 0, GPR64sp, asm_inst, "\t$Rd, $Rn, $imm6, $imm4",3179 (ins GPR64sp:$Rn, uimm6s16:$imm6, imm0_15:$imm4),3180 (set GPR64sp:$Rd, (OpNode GPR64sp:$Rn, imm0_63:$imm6, imm0_15:$imm4))> {3181 bits<6> imm6;3182 bits<4> imm4;3183 let Inst{31} = 1;3184 let Inst{23-22} = 0b10;3185 let Inst{21-16} = imm6;3186 let Inst{15-14} = 0b00;3187 let Inst{13-10} = imm4;3188 let Unpredictable{15-14} = 0b11;3189}3190 3191class SUBP<bit setsFlags, string asm_instr, SDPatternOperator OpNode>3192 : BaseTwoOperandRegReg<0b1, setsFlags, 0b000000, GPR64, asm_instr, OpNode,3193 GPR64sp, GPR64sp>;3194 3195//---3196// Extract3197//---3198def SDTA64EXTR : SDTypeProfile<1, 3, [SDTCisSameAs<0, 1>, SDTCisSameAs<0, 2>,3199 SDTCisPtrTy<3>]>;3200def AArch64Extr : SDNode<"AArch64ISD::EXTR", SDTA64EXTR>;3201 3202class BaseExtractImm<RegisterClass regtype, Operand imm_type, string asm,3203 list<dag> patterns>3204 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, imm_type:$imm),3205 asm, "\t$Rd, $Rn, $Rm, $imm", "", patterns>,3206 Sched<[WriteExtr, ReadExtrHi]> {3207 bits<5> Rd;3208 bits<5> Rn;3209 bits<5> Rm;3210 bits<6> imm;3211 3212 let Inst{30-23} = 0b00100111;3213 let Inst{21} = 0;3214 let Inst{20-16} = Rm;3215 let Inst{15-10} = imm;3216 let Inst{9-5} = Rn;3217 let Inst{4-0} = Rd;3218}3219 3220multiclass ExtractImm<string asm> {3221 def Wrri : BaseExtractImm<GPR32, imm0_31, asm,3222 [(set GPR32:$Rd,3223 (fshr GPR32:$Rn, GPR32:$Rm, imm0_31:$imm))]> {3224 let Inst{31} = 0;3225 let Inst{22} = 0;3226 // imm<5> must be zero.3227 let imm{5} = 0;3228 }3229 def Xrri : BaseExtractImm<GPR64, imm0_63, asm,3230 [(set GPR64:$Rd,3231 (fshr GPR64:$Rn, GPR64:$Rm, imm0_63:$imm))]> {3232 3233 let Inst{31} = 1;3234 let Inst{22} = 1;3235 }3236}3237 3238//---3239// Bitfield3240//---3241 3242let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in3243class BaseBitfieldImm<bits<2> opc,3244 RegisterClass regtype, Operand imm_type, string asm>3245 : I<(outs regtype:$Rd), (ins regtype:$Rn, imm_type:$immr, imm_type:$imms),3246 asm, "\t$Rd, $Rn, $immr, $imms", "", []>,3247 Sched<[WriteIS, ReadI]> {3248 bits<5> Rd;3249 bits<5> Rn;3250 bits<6> immr;3251 bits<6> imms;3252 3253 let Inst{30-29} = opc;3254 let Inst{28-23} = 0b100110;3255 let Inst{21-16} = immr;3256 let Inst{15-10} = imms;3257 let Inst{9-5} = Rn;3258 let Inst{4-0} = Rd;3259}3260 3261multiclass BitfieldImm<bits<2> opc, string asm> {3262 def Wri : BaseBitfieldImm<opc, GPR32, imm0_31, asm> {3263 let Inst{31} = 0;3264 let Inst{22} = 0;3265 // imms<5> and immr<5> must be zero, else ReservedValue().3266 let Inst{21} = 0;3267 let Inst{15} = 0;3268 }3269 def Xri : BaseBitfieldImm<opc, GPR64, imm0_63, asm> {3270 let Inst{31} = 1;3271 let Inst{22} = 1;3272 }3273}3274 3275let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in3276class BaseBitfieldImmWith2RegArgs<bits<2> opc,3277 RegisterClass regtype, Operand imm_type, string asm>3278 : I<(outs regtype:$Rd), (ins regtype:$src, regtype:$Rn, imm_type:$immr,3279 imm_type:$imms),3280 asm, "\t$Rd, $Rn, $immr, $imms", "$src = $Rd", []>,3281 Sched<[WriteIS, ReadI]> {3282 bits<5> Rd;3283 bits<5> Rn;3284 bits<6> immr;3285 bits<6> imms;3286 3287 let Inst{30-29} = opc;3288 let Inst{28-23} = 0b100110;3289 let Inst{21-16} = immr;3290 let Inst{15-10} = imms;3291 let Inst{9-5} = Rn;3292 let Inst{4-0} = Rd;3293}3294 3295multiclass BitfieldImmWith2RegArgs<bits<2> opc, string asm> {3296 def Wri : BaseBitfieldImmWith2RegArgs<opc, GPR32, imm0_31, asm> {3297 let Inst{31} = 0;3298 let Inst{22} = 0;3299 // imms<5> and immr<5> must be zero, else ReservedValue().3300 let Inst{21} = 0;3301 let Inst{15} = 0;3302 }3303 def Xri : BaseBitfieldImmWith2RegArgs<opc, GPR64, imm0_63, asm> {3304 let Inst{31} = 1;3305 let Inst{22} = 1;3306 }3307}3308 3309//---3310// Logical3311//---3312 3313// Logical (immediate)3314class BaseLogicalImm<bits<2> opc, RegisterClass dregtype,3315 RegisterClass sregtype, Operand imm_type, string asm,3316 list<dag> pattern>3317 : I<(outs dregtype:$Rd), (ins sregtype:$Rn, imm_type:$imm),3318 asm, "\t$Rd, $Rn, $imm", "", pattern>,3319 Sched<[WriteI, ReadI]> {3320 bits<5> Rd;3321 bits<5> Rn;3322 bits<13> imm;3323 let Inst{30-29} = opc;3324 let Inst{28-23} = 0b100100;3325 let Inst{22} = imm{12};3326 let Inst{21-16} = imm{11-6};3327 let Inst{15-10} = imm{5-0};3328 let Inst{9-5} = Rn;3329 let Inst{4-0} = Rd;3330 3331 let DecoderMethod = "DecodeLogicalImmInstruction";3332}3333 3334// Logical (shifted register)3335class BaseLogicalSReg<bits<2> opc, bit N, RegisterClass regtype,3336 logical_shifted_reg shifted_regtype, string asm,3337 list<dag> pattern>3338 : I<(outs regtype:$Rd), (ins regtype:$Rn, (shifted_regtype $Rm, $shift):$Rm_and_shift),3339 asm, "\t$Rd, $Rn, $Rm_and_shift", "", pattern>,3340 Sched<[WriteISReg, ReadI, ReadISReg]> {3341 bits<5> Rd;3342 bits<5> Rn;3343 bits<5> Rm;3344 bits<8> shift;3345 let Inst{30-29} = opc;3346 let Inst{28-24} = 0b01010;3347 let Inst{23-22} = shift{7-6};3348 let Inst{21} = N;3349 let Inst{20-16} = Rm;3350 let Inst{15-10} = shift{5-0};3351 let Inst{9-5} = Rn;3352 let Inst{4-0} = Rd;3353 3354 let DecoderMethod = "DecodeThreeAddrSRegInstruction";3355}3356 3357// Aliases for register+register logical instructions.3358class LogicalRegAlias<string asm, Instruction inst, RegisterClass regtype,3359 dag op2>3360 : InstAlias<asm#"\t$dst, $src1, $src2",3361 (inst regtype:$dst, regtype:$src1, op2)>;3362 3363multiclass LogicalImm<bits<2> opc, string mnemonic, SDNode OpNode,3364 string Alias> {3365 let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in3366 def Wri : BaseLogicalImm<opc, GPR32sp, GPR32, logical_imm32, mnemonic,3367 [(set GPR32sp:$Rd, (OpNode GPR32:$Rn,3368 logical_imm32:$imm))]> {3369 let Inst{31} = 0;3370 let Inst{22} = 0; // 64-bit version has an additional bit of immediate.3371 }3372 let AddedComplexity = 6, isReMaterializable = 1, isAsCheapAsAMove = 1 in3373 def Xri : BaseLogicalImm<opc, GPR64sp, GPR64, logical_imm64, mnemonic,3374 [(set GPR64sp:$Rd, (OpNode GPR64:$Rn,3375 logical_imm64:$imm))]> {3376 let Inst{31} = 1;3377 }3378 3379 def : InstSubst<Alias # "\t$Rd, $Rn, $imm",3380 (!cast<Instruction>(NAME # "Wri") GPR32sp:$Rd, GPR32:$Rn,3381 logical_imm32_not:$imm), 0>;3382 def : InstSubst<Alias # "\t$Rd, $Rn, $imm",3383 (!cast<Instruction>(NAME # "Xri") GPR64sp:$Rd, GPR64:$Rn,3384 logical_imm64_not:$imm), 0>;3385}3386 3387multiclass LogicalImmS<bits<2> opc, string mnemonic, SDNode OpNode,3388 string Alias> {3389 let isCompare = 1, Defs = [NZCV] in {3390 def Wri : BaseLogicalImm<opc, GPR32, GPR32, logical_imm32, mnemonic,3391 [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_imm32:$imm))]> {3392 let Inst{31} = 0;3393 let Inst{22} = 0; // 64-bit version has an additional bit of immediate.3394 }3395 def Xri : BaseLogicalImm<opc, GPR64, GPR64, logical_imm64, mnemonic,3396 [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_imm64:$imm))]> {3397 let Inst{31} = 1;3398 }3399 } // end Defs = [NZCV]3400 3401 def : InstSubst<Alias # "\t$Rd, $Rn, $imm",3402 (!cast<Instruction>(NAME # "Wri") GPR32:$Rd, GPR32:$Rn,3403 logical_imm32_not:$imm), 0>;3404 def : InstSubst<Alias # "\t$Rd, $Rn, $imm",3405 (!cast<Instruction>(NAME # "Xri") GPR64:$Rd, GPR64:$Rn,3406 logical_imm64_not:$imm), 0>;3407}3408 3409class BaseLogicalRegPseudo<RegisterClass regtype, SDPatternOperator OpNode>3410 : Pseudo<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),3411 [(set regtype:$Rd, (OpNode regtype:$Rn, regtype:$Rm))]>,3412 Sched<[WriteI, ReadI, ReadI]>;3413 3414// Split from LogicalImm as not all instructions have both.3415multiclass LogicalReg<bits<2> opc, bit N, string mnemonic,3416 SDPatternOperator OpNode, int AddedComplexityVal = 0> {3417 let isReMaterializable = 1, isAsCheapAsAMove = 1, AddedComplexity = AddedComplexityVal in {3418 def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>;3419 def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>;3420 }3421 3422 def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic,3423 [(set GPR32:$Rd, (OpNode GPR32:$Rn,3424 logical_shifted_reg32:$Rm_and_shift))]> {3425 let Inst{31} = 0;3426 }3427 def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic,3428 [(set GPR64:$Rd, (OpNode GPR64:$Rn,3429 logical_shifted_reg64:$Rm_and_shift))]> {3430 let Inst{31} = 1;3431 }3432 3433 def : LogicalRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"),3434 GPR32, (logical_shifted_reg32 GPR32:$src2, 0)>;3435 def : LogicalRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"),3436 GPR64, (logical_shifted_reg64 GPR64:$src2, 0)>;3437}3438 3439// Split from LogicalReg to allow setting NZCV Defs3440multiclass LogicalRegS<bits<2> opc, bit N, string mnemonic,3441 SDPatternOperator OpNode = null_frag> {3442 let Defs = [NZCV], mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {3443 def Wrr : BaseLogicalRegPseudo<GPR32, OpNode>;3444 def Xrr : BaseLogicalRegPseudo<GPR64, OpNode>;3445 3446 def Wrs : BaseLogicalSReg<opc, N, GPR32, logical_shifted_reg32, mnemonic,3447 [(set GPR32:$Rd, (OpNode GPR32:$Rn, logical_shifted_reg32:$Rm_and_shift))]> {3448 let Inst{31} = 0;3449 }3450 def Xrs : BaseLogicalSReg<opc, N, GPR64, logical_shifted_reg64, mnemonic,3451 [(set GPR64:$Rd, (OpNode GPR64:$Rn, logical_shifted_reg64:$Rm_and_shift))]> {3452 let Inst{31} = 1;3453 }3454 } // Defs = [NZCV]3455 3456 def : LogicalRegAlias<mnemonic, !cast<Instruction>(NAME#"Wrs"),3457 GPR32, (logical_shifted_reg32 GPR32:$src2, 0)>;3458 def : LogicalRegAlias<mnemonic, !cast<Instruction>(NAME#"Xrs"),3459 GPR64, (logical_shifted_reg64 GPR64:$src2, 0)>;3460}3461 3462//---3463// Conditionally set flags3464//---3465 3466let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in3467class BaseCondComparisonImm<bit op, RegisterClass regtype, ImmLeaf immtype,3468 string mnemonic, SDNode OpNode>3469 : I<(outs), (ins regtype:$Rn, immtype:$imm, imm32_0_15:$nzcv, ccode:$cond),3470 mnemonic, "\t$Rn, $imm, $nzcv, $cond", "",3471 [(set NZCV, (OpNode regtype:$Rn, immtype:$imm, (i32 imm:$nzcv),3472 (i32 imm:$cond), NZCV))]>,3473 Sched<[WriteI, ReadI]> {3474 let Uses = [NZCV];3475 let Defs = [NZCV];3476 3477 bits<5> Rn;3478 bits<5> imm;3479 bits<4> nzcv;3480 bits<4> cond;3481 3482 let Inst{30} = op;3483 let Inst{29-21} = 0b111010010;3484 let Inst{20-16} = imm;3485 let Inst{15-12} = cond;3486 let Inst{11-10} = 0b10;3487 let Inst{9-5} = Rn;3488 let Inst{4} = 0b0;3489 let Inst{3-0} = nzcv;3490}3491 3492let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in3493class BaseCondComparisonReg<bit op, RegisterClass regtype, string mnemonic,3494 SDNode OpNode>3495 : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond),3496 mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "",3497 [(set NZCV, (OpNode regtype:$Rn, regtype:$Rm, (i32 imm:$nzcv),3498 (i32 imm:$cond), NZCV))]>,3499 Sched<[WriteI, ReadI, ReadI]> {3500 let Uses = [NZCV];3501 let Defs = [NZCV];3502 3503 bits<5> Rn;3504 bits<5> Rm;3505 bits<4> nzcv;3506 bits<4> cond;3507 3508 let Inst{30} = op;3509 let Inst{29-21} = 0b111010010;3510 let Inst{20-16} = Rm;3511 let Inst{15-12} = cond;3512 let Inst{11-10} = 0b00;3513 let Inst{9-5} = Rn;3514 let Inst{4} = 0b0;3515 let Inst{3-0} = nzcv;3516}3517 3518multiclass CondComparison<bit op, string mnemonic, SDNode OpNode> {3519 // immediate operand variants3520 def Wi : BaseCondComparisonImm<op, GPR32, imm32_0_31, mnemonic, OpNode> {3521 let Inst{31} = 0;3522 }3523 def Xi : BaseCondComparisonImm<op, GPR64, imm0_31, mnemonic, OpNode> {3524 let Inst{31} = 1;3525 }3526 // register operand variants3527 def Wr : BaseCondComparisonReg<op, GPR32, mnemonic, OpNode> {3528 let Inst{31} = 0;3529 }3530 def Xr : BaseCondComparisonReg<op, GPR64, mnemonic, OpNode> {3531 let Inst{31} = 1;3532 }3533}3534 3535//---3536// Conditional select3537//---3538 3539class BaseCondSelect<bit op, bits<2> op2, RegisterClass regtype, string asm>3540 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond),3541 asm, "\t$Rd, $Rn, $Rm, $cond", "",3542 [(set regtype:$Rd,3543 (AArch64csel regtype:$Rn, regtype:$Rm, (i32 imm:$cond), NZCV))]>,3544 Sched<[WriteI, ReadI, ReadI]> {3545 let Uses = [NZCV];3546 3547 bits<5> Rd;3548 bits<5> Rn;3549 bits<5> Rm;3550 bits<4> cond;3551 3552 let Inst{30} = op;3553 let Inst{29-21} = 0b011010100;3554 let Inst{20-16} = Rm;3555 let Inst{15-12} = cond;3556 let Inst{11-10} = op2;3557 let Inst{9-5} = Rn;3558 let Inst{4-0} = Rd;3559}3560 3561multiclass CondSelect<bit op, bits<2> op2, string asm> {3562 def Wr : BaseCondSelect<op, op2, GPR32, asm> {3563 let Inst{31} = 0;3564 }3565 def Xr : BaseCondSelect<op, op2, GPR64, asm> {3566 let Inst{31} = 1;3567 }3568}3569 3570class BaseCondSelectOp<bit op, bits<2> op2, RegisterClass regtype, string asm,3571 PatFrag frag>3572 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond),3573 asm, "\t$Rd, $Rn, $Rm, $cond", "",3574 [(set regtype:$Rd,3575 (AArch64csel regtype:$Rn, (frag regtype:$Rm),3576 (i32 imm:$cond), NZCV))]>,3577 Sched<[WriteI, ReadI, ReadI]> {3578 let Uses = [NZCV];3579 3580 bits<5> Rd;3581 bits<5> Rn;3582 bits<5> Rm;3583 bits<4> cond;3584 3585 let Inst{30} = op;3586 let Inst{29-21} = 0b011010100;3587 let Inst{20-16} = Rm;3588 let Inst{15-12} = cond;3589 let Inst{11-10} = op2;3590 let Inst{9-5} = Rn;3591 let Inst{4-0} = Rd;3592}3593 3594def inv_cond_XFORM : SDNodeXForm<imm, [{3595 AArch64CC::CondCode CC = static_cast<AArch64CC::CondCode>(N->getZExtValue());3596 return CurDAG->getTargetConstant(AArch64CC::getInvertedCondCode(CC), SDLoc(N),3597 MVT::i32);3598}]>;3599 3600multiclass CondSelectOp<bit op, bits<2> op2, string asm, PatFrag frag> {3601 def Wr : BaseCondSelectOp<op, op2, GPR32, asm, frag> {3602 let Inst{31} = 0;3603 }3604 def Xr : BaseCondSelectOp<op, op2, GPR64, asm, frag> {3605 let Inst{31} = 1;3606 }3607 3608 def : Pat<(AArch64csel (frag GPR32:$Rm), GPR32:$Rn, (i32 imm:$cond), NZCV),3609 (!cast<Instruction>(NAME # Wr) GPR32:$Rn, GPR32:$Rm,3610 (inv_cond_XFORM imm:$cond))>;3611 3612 def : Pat<(AArch64csel (frag GPR64:$Rm), GPR64:$Rn, (i32 imm:$cond), NZCV),3613 (!cast<Instruction>(NAME # Xr) GPR64:$Rn, GPR64:$Rm,3614 (inv_cond_XFORM imm:$cond))>;3615}3616 3617//---3618// Special Mask Value3619//---3620def maski8_or_more : Operand<i32>,3621 ImmLeaf<i32, [{ return (Imm & 0xff) == 0xff; }]> {3622}3623def maski16_or_more : Operand<i32>,3624 ImmLeaf<i32, [{ return (Imm & 0xffff) == 0xffff; }]> {3625}3626 3627 3628//---3629// Load/store3630//---3631 3632// (unsigned immediate)3633// Indexed for 8-bit registers. offset is in range [0,4095].3634def am_indexed8 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed8", []>;3635def am_indexed16 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed16", []>;3636def am_indexed32 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed32", []>;3637def am_indexed64 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed64", []>;3638def am_indexed128 : ComplexPattern<iPTR, 2, "SelectAddrModeIndexed128", []>;3639 3640// (unsigned immediate)3641// Indexed for 8-bit registers. offset is in range [0,63].3642def am_indexed8_6b : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedUImm<1,63>", []>;3643def am_indexed16_6b : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedUImm<2,63>", []>;3644def am_indexed32_6b : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedUImm<4,63>", []>;3645def am_indexed64_6b : ComplexPattern<iPTR, 2, "SelectAddrModeIndexedUImm<8,63>", []>;3646 3647def gi_am_indexed8 :3648 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<8>">,3649 GIComplexPatternEquiv<am_indexed8>;3650def gi_am_indexed16 :3651 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<16>">,3652 GIComplexPatternEquiv<am_indexed16>;3653def gi_am_indexed32 :3654 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<32>">,3655 GIComplexPatternEquiv<am_indexed32>;3656def gi_am_indexed64 :3657 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<64>">,3658 GIComplexPatternEquiv<am_indexed64>;3659def gi_am_indexed128 :3660 GIComplexOperandMatcher<s64, "selectAddrModeIndexed<128>">,3661 GIComplexPatternEquiv<am_indexed128>;3662 3663class UImm12OffsetOperand<int Scale> : AsmOperandClass {3664 let Name = "UImm12Offset" # Scale;3665 let RenderMethod = "addUImm12OffsetOperands<" # Scale # ">";3666 let PredicateMethod = "isUImm12Offset<" # Scale # ">";3667 let DiagnosticType = "InvalidMemoryIndexed" # Scale;3668}3669 3670def UImm12OffsetScale1Operand : UImm12OffsetOperand<1>;3671def UImm12OffsetScale2Operand : UImm12OffsetOperand<2>;3672def UImm12OffsetScale4Operand : UImm12OffsetOperand<4>;3673def UImm12OffsetScale8Operand : UImm12OffsetOperand<8>;3674def UImm12OffsetScale16Operand : UImm12OffsetOperand<16>;3675 3676class uimm12_scaled<int Scale> : Operand<i64> {3677 let ParserMatchClass3678 = !cast<AsmOperandClass>("UImm12OffsetScale" # Scale # "Operand");3679 let EncoderMethod3680 = "getLdStUImm12OpValue<AArch64::fixup_aarch64_ldst_imm12_scale" # Scale # ">";3681 let PrintMethod = "printUImm12Offset<" # Scale # ">";3682}3683 3684def uimm12s1 : uimm12_scaled<1>;3685def uimm12s2 : uimm12_scaled<2>;3686def uimm12s4 : uimm12_scaled<4>;3687def uimm12s8 : uimm12_scaled<8>;3688def uimm12s16 : uimm12_scaled<16>;3689 3690class BaseLoadStoreUI<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,3691 string asm, list<dag> pattern>3692 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> {3693 bits<5> Rt;3694 3695 bits<5> Rn;3696 bits<12> offset;3697 3698 let Inst{31-30} = sz;3699 let Inst{29-27} = 0b111;3700 let Inst{26} = V;3701 let Inst{25-24} = 0b01;3702 let Inst{23-22} = opc;3703 let Inst{21-10} = offset;3704 let Inst{9-5} = Rn;3705 let Inst{4-0} = Rt;3706 3707 let DecoderMethod = "DecodeUnsignedLdStInstruction";3708}3709 3710multiclass LoadUI<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype,3711 Operand indextype, string asm, list<dag> pattern> {3712 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in3713 def ui : BaseLoadStoreUI<sz, V, opc, (outs regtype:$Rt),3714 (ins GPR64sp:$Rn, indextype:$offset),3715 asm, pattern>,3716 Sched<[WriteLD]>;3717 3718 def : InstAlias<asm # "\t$Rt, [$Rn]",3719 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>;3720}3721 3722multiclass StoreUI<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype,3723 Operand indextype, string asm, list<dag> pattern> {3724 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in3725 def ui : BaseLoadStoreUI<sz, V, opc, (outs),3726 (ins regtype:$Rt, GPR64sp:$Rn, indextype:$offset),3727 asm, pattern>,3728 Sched<[WriteST]>;3729 3730 def : InstAlias<asm # "\t$Rt, [$Rn]",3731 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>;3732}3733 3734// Same as StoreUI, but take a RegisterOperand. This is used by GlobalISel to3735// substitute zero-registers automatically.3736//3737// TODO: Roll out zero-register substitution to GPR32/GPR64 and fold this back3738// into StoreUI.3739multiclass StoreUIz<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,3740 Operand indextype, string asm, list<dag> pattern> {3741 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in3742 def ui : BaseLoadStoreUI<sz, V, opc, (outs),3743 (ins regtype:$Rt, GPR64sp:$Rn, indextype:$offset),3744 asm, pattern>,3745 Sched<[WriteST]>;3746 3747 def : InstAlias<asm # "\t$Rt, [$Rn]",3748 (!cast<Instruction>(NAME # "ui") regtype:$Rt, GPR64sp:$Rn, 0)>;3749}3750 3751def PrefetchOperand : AsmOperandClass {3752 let Name = "Prefetch";3753 let ParserMethod = "tryParsePrefetch";3754}3755def prfop : Operand<i32> {3756 let PrintMethod = "printPrefetchOp";3757 let ParserMatchClass = PrefetchOperand;3758}3759 3760let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in3761class PrefetchUI<bits<2> sz, bit V, bits<2> opc, string asm, list<dag> pat>3762 : BaseLoadStoreUI<sz, V, opc,3763 (outs), (ins prfop:$Rt, GPR64sp:$Rn, uimm12s8:$offset),3764 asm, pat>,3765 Sched<[WriteLD]>;3766 3767//---3768// Load literal3769//---3770 3771// Load literal address: 19-bit immediate. The low two bits of the target3772// offset are implied zero and so are not part of the immediate.3773def am_ldrlit : Operand<iPTR> {3774 let EncoderMethod = "getLoadLiteralOpValue";3775 let DecoderMethod = "DecodePCRelLabel19";3776 let PrintMethod = "printAlignedLabel";3777 let ParserMatchClass = PCRelLabel19Operand;3778 let OperandType = "OPERAND_PCREL";3779}3780 3781let mayLoad = 1, mayStore = 0, hasSideEffects = 0, AddedComplexity = 20 in3782class LoadLiteral<bits<2> opc, bit V, RegisterOperand regtype, string asm, list<dag> pat>3783 : I<(outs regtype:$Rt), (ins am_ldrlit:$label),3784 asm, "\t$Rt, $label", "", pat>,3785 Sched<[WriteLD]> {3786 bits<5> Rt;3787 bits<19> label;3788 let Inst{31-30} = opc;3789 let Inst{29-27} = 0b011;3790 let Inst{26} = V;3791 let Inst{25-24} = 0b00;3792 let Inst{23-5} = label;3793 let Inst{4-0} = Rt;3794}3795 3796let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in3797class PrefetchLiteral<bits<2> opc, bit V, string asm, list<dag> pat>3798 : I<(outs), (ins prfop:$Rt, am_ldrlit:$label),3799 asm, "\t$Rt, $label", "", pat>,3800 Sched<[WriteLD]> {3801 bits<5> Rt;3802 bits<19> label;3803 let Inst{31-30} = opc;3804 let Inst{29-27} = 0b011;3805 let Inst{26} = V;3806 let Inst{25-24} = 0b00;3807 let Inst{23-5} = label;3808 let Inst{4-0} = Rt;3809}3810 3811//---3812// Load/store register offset3813//---3814 3815def ro_Xindexed8 : ComplexPattern<iPTR, 4, "SelectAddrModeXRO<8>", []>;3816def ro_Xindexed16 : ComplexPattern<iPTR, 4, "SelectAddrModeXRO<16>", []>;3817def ro_Xindexed32 : ComplexPattern<iPTR, 4, "SelectAddrModeXRO<32>", []>;3818def ro_Xindexed64 : ComplexPattern<iPTR, 4, "SelectAddrModeXRO<64>", []>;3819def ro_Xindexed128 : ComplexPattern<iPTR, 4, "SelectAddrModeXRO<128>", []>;3820 3821def gi_ro_Xindexed8 :3822 GIComplexOperandMatcher<s64, "selectAddrModeXRO<8>">,3823 GIComplexPatternEquiv<ro_Xindexed8>;3824def gi_ro_Xindexed16 :3825 GIComplexOperandMatcher<s64, "selectAddrModeXRO<16>">,3826 GIComplexPatternEquiv<ro_Xindexed16>;3827def gi_ro_Xindexed32 :3828 GIComplexOperandMatcher<s64, "selectAddrModeXRO<32>">,3829 GIComplexPatternEquiv<ro_Xindexed32>;3830def gi_ro_Xindexed64 :3831 GIComplexOperandMatcher<s64, "selectAddrModeXRO<64>">,3832 GIComplexPatternEquiv<ro_Xindexed64>;3833def gi_ro_Xindexed128 :3834 GIComplexOperandMatcher<s64, "selectAddrModeXRO<128>">,3835 GIComplexPatternEquiv<ro_Xindexed128>;3836 3837def ro_Windexed8 : ComplexPattern<iPTR, 4, "SelectAddrModeWRO<8>", []>;3838def ro_Windexed16 : ComplexPattern<iPTR, 4, "SelectAddrModeWRO<16>", []>;3839def ro_Windexed32 : ComplexPattern<iPTR, 4, "SelectAddrModeWRO<32>", []>;3840def ro_Windexed64 : ComplexPattern<iPTR, 4, "SelectAddrModeWRO<64>", []>;3841def ro_Windexed128 : ComplexPattern<iPTR, 4, "SelectAddrModeWRO<128>", []>;3842 3843def gi_ro_Windexed8 :3844 GIComplexOperandMatcher<s64, "selectAddrModeWRO<8>">,3845 GIComplexPatternEquiv<ro_Windexed8>;3846def gi_ro_Windexed16 :3847 GIComplexOperandMatcher<s64, "selectAddrModeWRO<16>">,3848 GIComplexPatternEquiv<ro_Windexed16>;3849def gi_ro_Windexed32 :3850 GIComplexOperandMatcher<s64, "selectAddrModeWRO<32>">,3851 GIComplexPatternEquiv<ro_Windexed32>;3852def gi_ro_Windexed64 :3853 GIComplexOperandMatcher<s64, "selectAddrModeWRO<64>">,3854 GIComplexPatternEquiv<ro_Windexed64>;3855def gi_ro_Windexed128 :3856 GIComplexOperandMatcher<s64, "selectAddrModeWRO<128>">,3857 GIComplexPatternEquiv<ro_Windexed128>;3858 3859class MemExtendOperand<string Reg, int Width> : AsmOperandClass {3860 let Name = "Mem" # Reg # "Extend" # Width;3861 let PredicateMethod = "isMem" # Reg # "Extend<" # Width # ">";3862 let RenderMethod = "addMemExtendOperands";3863 let DiagnosticType = "InvalidMemory" # Reg # "Extend" # Width;3864}3865 3866def MemWExtend8Operand : MemExtendOperand<"W", 8> {3867 // The address "[x0, x1, lsl #0]" actually maps to the variant which performs3868 // the trivial shift.3869 let RenderMethod = "addMemExtend8Operands";3870}3871def MemWExtend16Operand : MemExtendOperand<"W", 16>;3872def MemWExtend32Operand : MemExtendOperand<"W", 32>;3873def MemWExtend64Operand : MemExtendOperand<"W", 64>;3874def MemWExtend128Operand : MemExtendOperand<"W", 128>;3875 3876def MemXExtend8Operand : MemExtendOperand<"X", 8> {3877 // The address "[x0, x1, lsl #0]" actually maps to the variant which performs3878 // the trivial shift.3879 let RenderMethod = "addMemExtend8Operands";3880}3881def MemXExtend16Operand : MemExtendOperand<"X", 16>;3882def MemXExtend32Operand : MemExtendOperand<"X", 32>;3883def MemXExtend64Operand : MemExtendOperand<"X", 64>;3884def MemXExtend128Operand : MemExtendOperand<"X", 128>;3885 3886class ro_extend<AsmOperandClass ParserClass, string Reg, int Width>3887 : Operand<i32> {3888 let ParserMatchClass = ParserClass;3889 let PrintMethod = "printMemExtend<'" # Reg # "', " # Width # ">";3890 let DecoderMethod = "DecodeMemExtend";3891 let EncoderMethod = "getMemExtendOpValue";3892 let MIOperandInfo = (ops i32imm:$signed, i32imm:$doshift);3893}3894 3895def ro_Wextend8 : ro_extend<MemWExtend8Operand, "w", 8>;3896def ro_Wextend16 : ro_extend<MemWExtend16Operand, "w", 16>;3897def ro_Wextend32 : ro_extend<MemWExtend32Operand, "w", 32>;3898def ro_Wextend64 : ro_extend<MemWExtend64Operand, "w", 64>;3899def ro_Wextend128 : ro_extend<MemWExtend128Operand, "w", 128>;3900 3901def ro_Xextend8 : ro_extend<MemXExtend8Operand, "x", 8>;3902def ro_Xextend16 : ro_extend<MemXExtend16Operand, "x", 16>;3903def ro_Xextend32 : ro_extend<MemXExtend32Operand, "x", 32>;3904def ro_Xextend64 : ro_extend<MemXExtend64Operand, "x", 64>;3905def ro_Xextend128 : ro_extend<MemXExtend128Operand, "x", 128>;3906 3907class ROAddrMode<ComplexPattern windex, ComplexPattern xindex,3908 Operand wextend, Operand xextend> {3909 // CodeGen-level pattern covering the entire addressing mode.3910 ComplexPattern Wpat = windex;3911 ComplexPattern Xpat = xindex;3912 3913 // Asm-level Operand covering the valid "uxtw #3" style syntax.3914 Operand Wext = wextend;3915 Operand Xext = xextend;3916}3917 3918def ro8 : ROAddrMode<ro_Windexed8, ro_Xindexed8, ro_Wextend8, ro_Xextend8>;3919def ro16 : ROAddrMode<ro_Windexed16, ro_Xindexed16, ro_Wextend16, ro_Xextend16>;3920def ro32 : ROAddrMode<ro_Windexed32, ro_Xindexed32, ro_Wextend32, ro_Xextend32>;3921def ro64 : ROAddrMode<ro_Windexed64, ro_Xindexed64, ro_Wextend64, ro_Xextend64>;3922def ro128 : ROAddrMode<ro_Windexed128, ro_Xindexed128, ro_Wextend128,3923 ro_Xextend128>;3924 3925class LoadStore8RO<bits<2> sz, bit V, bits<2> opc, string asm, dag ins,3926 dag outs, list<dag> pat>3927 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {3928 bits<5> Rt;3929 bits<5> Rn;3930 bits<5> Rm;3931 bits<2> extend;3932 let Inst{31-30} = sz;3933 let Inst{29-27} = 0b111;3934 let Inst{26} = V;3935 let Inst{25-24} = 0b00;3936 let Inst{23-22} = opc;3937 let Inst{21} = 1;3938 let Inst{20-16} = Rm;3939 let Inst{15} = extend{1}; // sign extend Rm?3940 let Inst{14} = 1;3941 let Inst{12} = extend{0}; // do shift?3942 let Inst{11-10} = 0b10;3943 let Inst{9-5} = Rn;3944 let Inst{4-0} = Rt;3945}3946 3947class ROInstAlias<string asm, DAGOperand regtype, Instruction INST,3948 ro_extend ext>3949 : InstAlias<asm # "\t$Rt, [$Rn, $Rm]",3950 (INST regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, (ext 0, 0))>;3951 3952multiclass Load8RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype,3953 string asm, ValueType Ty, SDPatternOperator loadop> {3954 let AddedComplexity = 10 in3955 def roW : LoadStore8RO<sz, V, opc, asm,3956 (outs regtype:$Rt),3957 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend),3958 [(set (Ty regtype:$Rt),3959 (loadop (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm,3960 ro_Wextend8:$extend)))]>,3961 Sched<[WriteLDIdx, ReadAdrBase]> {3962 let Inst{13} = 0b0;3963 }3964 3965 let AddedComplexity = 10 in3966 def roX : LoadStore8RO<sz, V, opc, asm,3967 (outs regtype:$Rt),3968 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend),3969 [(set (Ty regtype:$Rt),3970 (loadop (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm,3971 ro_Xextend8:$extend)))]>,3972 Sched<[WriteLDIdx, ReadAdrBase]> {3973 let Inst{13} = 0b1;3974 }3975 3976 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX"), ro_Xextend8>;3977}3978 3979multiclass Store8RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype,3980 string asm, ValueType Ty, SDPatternOperator storeop> {3981 let AddedComplexity = 10 in3982 def roW : LoadStore8RO<sz, V, opc, asm, (outs),3983 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend8:$extend),3984 [(storeop (Ty regtype:$Rt),3985 (ro_Windexed8 GPR64sp:$Rn, GPR32:$Rm,3986 ro_Wextend8:$extend))]>,3987 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> {3988 let Inst{13} = 0b0;3989 }3990 3991 let AddedComplexity = 10 in3992 def roX : LoadStore8RO<sz, V, opc, asm, (outs),3993 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend8:$extend),3994 [(storeop (Ty regtype:$Rt),3995 (ro_Xindexed8 GPR64sp:$Rn, GPR64:$Rm,3996 ro_Xextend8:$extend))]>,3997 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> {3998 let Inst{13} = 0b1;3999 }4000 4001 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX"), ro_Xextend8>;4002}4003 4004class LoadStore16RO<bits<2> sz, bit V, bits<2> opc, string asm, dag ins,4005 dag outs, list<dag> pat>4006 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {4007 bits<5> Rt;4008 bits<5> Rn;4009 bits<5> Rm;4010 bits<2> extend;4011 let Inst{31-30} = sz;4012 let Inst{29-27} = 0b111;4013 let Inst{26} = V;4014 let Inst{25-24} = 0b00;4015 let Inst{23-22} = opc;4016 let Inst{21} = 1;4017 let Inst{20-16} = Rm;4018 let Inst{15} = extend{1}; // sign extend Rm?4019 let Inst{14} = 1;4020 let Inst{12} = extend{0}; // do shift?4021 let Inst{11-10} = 0b10;4022 let Inst{9-5} = Rn;4023 let Inst{4-0} = Rt;4024}4025 4026multiclass Load16RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype,4027 string asm, ValueType Ty, SDPatternOperator loadop> {4028 let AddedComplexity = 10 in4029 def roW : LoadStore16RO<sz, V, opc, asm, (outs regtype:$Rt),4030 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend),4031 [(set (Ty regtype:$Rt),4032 (loadop (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm,4033 ro_Wextend16:$extend)))]>,4034 Sched<[WriteLDIdx, ReadAdrBase]> {4035 let Inst{13} = 0b0;4036 }4037 4038 let AddedComplexity = 10 in4039 def roX : LoadStore16RO<sz, V, opc, asm, (outs regtype:$Rt),4040 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend),4041 [(set (Ty regtype:$Rt),4042 (loadop (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm,4043 ro_Xextend16:$extend)))]>,4044 Sched<[WriteLDIdx, ReadAdrBase]> {4045 let Inst{13} = 0b1;4046 }4047 4048 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX"), ro_Xextend16>;4049}4050 4051multiclass Store16RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype,4052 string asm, ValueType Ty, SDPatternOperator storeop> {4053 let AddedComplexity = 10 in4054 def roW : LoadStore16RO<sz, V, opc, asm, (outs),4055 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend16:$extend),4056 [(storeop (Ty regtype:$Rt),4057 (ro_Windexed16 GPR64sp:$Rn, GPR32:$Rm,4058 ro_Wextend16:$extend))]>,4059 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> {4060 let Inst{13} = 0b0;4061 }4062 4063 let AddedComplexity = 10 in4064 def roX : LoadStore16RO<sz, V, opc, asm, (outs),4065 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend16:$extend),4066 [(storeop (Ty regtype:$Rt),4067 (ro_Xindexed16 GPR64sp:$Rn, GPR64:$Rm,4068 ro_Xextend16:$extend))]>,4069 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> {4070 let Inst{13} = 0b1;4071 }4072 4073 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX"), ro_Xextend16>;4074}4075 4076class LoadStore32RO<bits<2> sz, bit V, bits<2> opc, string asm, dag ins,4077 dag outs, list<dag> pat>4078 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {4079 bits<5> Rt;4080 bits<5> Rn;4081 bits<5> Rm;4082 bits<2> extend;4083 let Inst{31-30} = sz;4084 let Inst{29-27} = 0b111;4085 let Inst{26} = V;4086 let Inst{25-24} = 0b00;4087 let Inst{23-22} = opc;4088 let Inst{21} = 1;4089 let Inst{20-16} = Rm;4090 let Inst{15} = extend{1}; // sign extend Rm?4091 let Inst{14} = 1;4092 let Inst{12} = extend{0}; // do shift?4093 let Inst{11-10} = 0b10;4094 let Inst{9-5} = Rn;4095 let Inst{4-0} = Rt;4096}4097 4098multiclass Load32RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype,4099 string asm, ValueType Ty, SDPatternOperator loadop> {4100 let AddedComplexity = 10 in4101 def roW : LoadStore32RO<sz, V, opc, asm, (outs regtype:$Rt),4102 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend),4103 [(set (Ty regtype:$Rt),4104 (loadop (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm,4105 ro_Wextend32:$extend)))]>,4106 Sched<[WriteLDIdx, ReadAdrBase]> {4107 let Inst{13} = 0b0;4108 }4109 4110 let AddedComplexity = 10 in4111 def roX : LoadStore32RO<sz, V, opc, asm, (outs regtype:$Rt),4112 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend),4113 [(set (Ty regtype:$Rt),4114 (loadop (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm,4115 ro_Xextend32:$extend)))]>,4116 Sched<[WriteLDIdx, ReadAdrBase]> {4117 let Inst{13} = 0b1;4118 }4119 4120 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX"), ro_Xextend32>;4121}4122 4123multiclass Store32RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype,4124 string asm, ValueType Ty, SDPatternOperator storeop> {4125 let AddedComplexity = 10 in4126 def roW : LoadStore32RO<sz, V, opc, asm, (outs),4127 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend32:$extend),4128 [(storeop (Ty regtype:$Rt),4129 (ro_Windexed32 GPR64sp:$Rn, GPR32:$Rm,4130 ro_Wextend32:$extend))]>,4131 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> {4132 let Inst{13} = 0b0;4133 }4134 4135 let AddedComplexity = 10 in4136 def roX : LoadStore32RO<sz, V, opc, asm, (outs),4137 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend32:$extend),4138 [(storeop (Ty regtype:$Rt),4139 (ro_Xindexed32 GPR64sp:$Rn, GPR64:$Rm,4140 ro_Xextend32:$extend))]>,4141 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> {4142 let Inst{13} = 0b1;4143 }4144 4145 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX"), ro_Xextend32>;4146}4147 4148class LoadStore64RO<bits<2> sz, bit V, bits<2> opc, string asm, dag ins,4149 dag outs, list<dag> pat>4150 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {4151 bits<5> Rt;4152 bits<5> Rn;4153 bits<5> Rm;4154 bits<2> extend;4155 let Inst{31-30} = sz;4156 let Inst{29-27} = 0b111;4157 let Inst{26} = V;4158 let Inst{25-24} = 0b00;4159 let Inst{23-22} = opc;4160 let Inst{21} = 1;4161 let Inst{20-16} = Rm;4162 let Inst{15} = extend{1}; // sign extend Rm?4163 let Inst{14} = 1;4164 let Inst{12} = extend{0}; // do shift?4165 let Inst{11-10} = 0b10;4166 let Inst{9-5} = Rn;4167 let Inst{4-0} = Rt;4168}4169 4170multiclass Load64RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype,4171 string asm, ValueType Ty, SDPatternOperator loadop> {4172 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in4173 def roW : LoadStore64RO<sz, V, opc, asm, (outs regtype:$Rt),4174 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend),4175 [(set (Ty regtype:$Rt),4176 (loadop (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm,4177 ro_Wextend64:$extend)))]>,4178 Sched<[WriteLDIdx, ReadAdrBase]> {4179 let Inst{13} = 0b0;4180 }4181 4182 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in4183 def roX : LoadStore64RO<sz, V, opc, asm, (outs regtype:$Rt),4184 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend),4185 [(set (Ty regtype:$Rt),4186 (loadop (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm,4187 ro_Xextend64:$extend)))]>,4188 Sched<[WriteLDIdx, ReadAdrBase]> {4189 let Inst{13} = 0b1;4190 }4191 4192 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX"), ro_Xextend64>;4193}4194 4195multiclass Store64RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype,4196 string asm, ValueType Ty, SDPatternOperator storeop> {4197 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in4198 def roW : LoadStore64RO<sz, V, opc, asm, (outs),4199 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend),4200 [(storeop (Ty regtype:$Rt),4201 (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm,4202 ro_Wextend64:$extend))]>,4203 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> {4204 let Inst{13} = 0b0;4205 }4206 4207 let AddedComplexity = 10, mayLoad = 0, mayStore = 1, hasSideEffects = 0 in4208 def roX : LoadStore64RO<sz, V, opc, asm, (outs),4209 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend),4210 [(storeop (Ty regtype:$Rt),4211 (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm,4212 ro_Xextend64:$extend))]>,4213 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> {4214 let Inst{13} = 0b1;4215 }4216 4217 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX"), ro_Xextend64>;4218}4219 4220class LoadStore128RO<bits<2> sz, bit V, bits<2> opc, string asm, dag ins,4221 dag outs, list<dag> pat>4222 : I<ins, outs, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat> {4223 bits<5> Rt;4224 bits<5> Rn;4225 bits<5> Rm;4226 bits<2> extend;4227 let Inst{31-30} = sz;4228 let Inst{29-27} = 0b111;4229 let Inst{26} = V;4230 let Inst{25-24} = 0b00;4231 let Inst{23-22} = opc;4232 let Inst{21} = 1;4233 let Inst{20-16} = Rm;4234 let Inst{15} = extend{1}; // sign extend Rm?4235 let Inst{14} = 1;4236 let Inst{12} = extend{0}; // do shift?4237 let Inst{11-10} = 0b10;4238 let Inst{9-5} = Rn;4239 let Inst{4-0} = Rt;4240}4241 4242multiclass Load128RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype,4243 string asm, ValueType Ty, SDPatternOperator loadop> {4244 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in4245 def roW : LoadStore128RO<sz, V, opc, asm, (outs regtype:$Rt),4246 (ins GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend),4247 [(set (Ty regtype:$Rt),4248 (loadop (ro_Windexed128 GPR64sp:$Rn, GPR32:$Rm,4249 ro_Wextend128:$extend)))]>,4250 Sched<[WriteLDIdx, ReadAdrBase]> {4251 let Inst{13} = 0b0;4252 }4253 4254 let AddedComplexity = 10, mayLoad = 1, mayStore = 0, hasSideEffects = 0 in4255 def roX : LoadStore128RO<sz, V, opc, asm, (outs regtype:$Rt),4256 (ins GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend),4257 [(set (Ty regtype:$Rt),4258 (loadop (ro_Xindexed128 GPR64sp:$Rn, GPR64:$Rm,4259 ro_Xextend128:$extend)))]>,4260 Sched<[WriteLDIdx, ReadAdrBase]> {4261 let Inst{13} = 0b1;4262 }4263 4264 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX"), ro_Xextend128>;4265}4266 4267multiclass Store128RO<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype,4268 string asm> {4269 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in4270 def roW : LoadStore128RO<sz, V, opc, asm, (outs),4271 (ins regtype:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend128:$extend),4272 []>,4273 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> {4274 let Inst{13} = 0b0;4275 }4276 4277 let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in4278 def roX : LoadStore128RO<sz, V, opc, asm, (outs),4279 (ins regtype:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend128:$extend),4280 []>,4281 Sched<[WriteSTIdx, ReadST, ReadAdrBase]> {4282 let Inst{13} = 0b1;4283 }4284 4285 def : ROInstAlias<asm, regtype, !cast<Instruction>(NAME # "roX"), ro_Xextend128>;4286}4287 4288let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in4289class BasePrefetchRO<bits<2> sz, bit V, bits<2> opc, dag outs, dag ins,4290 string asm, list<dag> pat>4291 : I<outs, ins, asm, "\t$Rt, [$Rn, $Rm, $extend]", "", pat>,4292 Sched<[WriteLD]> {4293 bits<5> Rt;4294 bits<5> Rn;4295 bits<5> Rm;4296 bits<2> extend;4297 let Inst{31-30} = sz;4298 let Inst{29-27} = 0b111;4299 let Inst{26} = V;4300 let Inst{25-24} = 0b00;4301 let Inst{23-22} = opc;4302 let Inst{21} = 1;4303 let Inst{20-16} = Rm;4304 let Inst{15} = extend{1}; // sign extend Rm?4305 let Inst{14} = 1;4306 let Inst{12} = extend{0}; // do shift?4307 let Inst{11-10} = 0b10;4308 let Inst{9-5} = Rn;4309 let Inst{4-0} = Rt;4310 let DecoderMethod = "DecodePRFMRegInstruction";4311 // PRFM (reg) aliases with RPRFM added to the base A64 instruction set. When4312 // the decoder method returns Fail, the decoder should attempt to decode the4313 // instruction as RPRFM.4314 let hasCompleteDecoder = 0;4315}4316 4317multiclass PrefetchRO<bits<2> sz, bit V, bits<2> opc, string asm> {4318 def roW : BasePrefetchRO<sz, V, opc, (outs),4319 (ins prfop:$Rt, GPR64sp:$Rn, GPR32:$Rm, ro_Wextend64:$extend),4320 asm, [(AArch64Prefetch timm:$Rt,4321 (ro_Windexed64 GPR64sp:$Rn, GPR32:$Rm,4322 ro_Wextend64:$extend))]> {4323 let Inst{13} = 0b0;4324 }4325 4326 def roX : BasePrefetchRO<sz, V, opc, (outs),4327 (ins prfop:$Rt, GPR64sp:$Rn, GPR64:$Rm, ro_Xextend64:$extend),4328 asm, [(AArch64Prefetch timm:$Rt,4329 (ro_Xindexed64 GPR64sp:$Rn, GPR64:$Rm,4330 ro_Xextend64:$extend))]> {4331 let Inst{13} = 0b1;4332 }4333 4334 def : ROInstAlias<"prfm", prfop, !cast<Instruction>(NAME # "roX"), ro_Xextend64>;4335}4336 4337//---4338// Load/store unscaled immediate4339//---4340 4341def am_unscaled8 : ComplexPattern<iPTR, 2, "SelectAddrModeUnscaled8", []>;4342def am_unscaled16 : ComplexPattern<iPTR, 2, "SelectAddrModeUnscaled16", []>;4343def am_unscaled32 : ComplexPattern<iPTR, 2, "SelectAddrModeUnscaled32", []>;4344def am_unscaled64 : ComplexPattern<iPTR, 2, "SelectAddrModeUnscaled64", []>;4345def am_unscaled128 :ComplexPattern<iPTR, 2, "SelectAddrModeUnscaled128", []>;4346 4347def gi_am_unscaled8 :4348 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled8">,4349 GIComplexPatternEquiv<am_unscaled8>;4350def gi_am_unscaled16 :4351 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled16">,4352 GIComplexPatternEquiv<am_unscaled16>;4353def gi_am_unscaled32 :4354 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled32">,4355 GIComplexPatternEquiv<am_unscaled32>;4356def gi_am_unscaled64 :4357 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled64">,4358 GIComplexPatternEquiv<am_unscaled64>;4359def gi_am_unscaled128 :4360 GIComplexOperandMatcher<s64, "selectAddrModeUnscaled128">,4361 GIComplexPatternEquiv<am_unscaled128>;4362 4363 4364class BaseLoadStoreUnscale<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,4365 string asm, list<dag> pattern>4366 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", pattern> {4367 bits<5> Rt;4368 bits<5> Rn;4369 bits<9> offset;4370 let Inst{31-30} = sz;4371 let Inst{29-27} = 0b111;4372 let Inst{26} = V;4373 let Inst{25-24} = 0b00;4374 let Inst{23-22} = opc;4375 let Inst{21} = 0;4376 let Inst{20-12} = offset;4377 let Inst{11-10} = 0b00;4378 let Inst{9-5} = Rn;4379 let Inst{4-0} = Rt;4380 4381 let DecoderMethod = "DecodeSignedLdStInstruction";4382}4383 4384// Armv8.4 LDAPR & STLR with Immediate Offset instruction4385multiclass BaseLoadUnscaleV84<string asm, bits<2> sz, bits<2> opc,4386 DAGOperand regtype > {4387 def i : BaseLoadStoreUnscale<sz, 0, opc, (outs regtype:$Rt),4388 (ins GPR64sp:$Rn, simm9:$offset), asm, []>,4389 Sched<[WriteST]> {4390 let Inst{29} = 0;4391 let Inst{24} = 1;4392 }4393 def : InstAlias<asm # "\t$Rt, [$Rn]",4394 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;4395}4396 4397multiclass BaseStoreUnscaleV84<string asm, bits<2> sz, bits<2> opc,4398 DAGOperand regtype > {4399 def i : BaseLoadStoreUnscale<sz, 0, opc, (outs),4400 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),4401 asm, []>,4402 Sched<[WriteST]> {4403 let Inst{29} = 0;4404 let Inst{24} = 1;4405 }4406 def : InstAlias<asm # "\t$Rt, [$Rn]",4407 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;4408}4409 4410multiclass LoadUnscaled<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype,4411 string asm, list<dag> pattern> {4412 let AddedComplexity = 1 in // try this before LoadUI4413 def i : BaseLoadStoreUnscale<sz, V, opc, (outs regtype:$Rt),4414 (ins GPR64sp:$Rn, simm9:$offset), asm, pattern>,4415 Sched<[WriteLD]>;4416 4417 def : InstAlias<asm # "\t$Rt, [$Rn]",4418 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;4419}4420 4421multiclass StoreUnscaled<bits<2> sz, bit V, bits<2> opc, DAGOperand regtype,4422 string asm, list<dag> pattern> {4423 let AddedComplexity = 1 in // try this before StoreUI4424 def i : BaseLoadStoreUnscale<sz, V, opc, (outs),4425 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),4426 asm, pattern>,4427 Sched<[WriteST]>;4428 4429 def : InstAlias<asm # "\t$Rt, [$Rn]",4430 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;4431}4432 4433multiclass PrefetchUnscaled<bits<2> sz, bit V, bits<2> opc, string asm,4434 list<dag> pat> {4435 let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in4436 def i : BaseLoadStoreUnscale<sz, V, opc, (outs),4437 (ins prfop:$Rt, GPR64sp:$Rn, simm9:$offset),4438 asm, pat>,4439 Sched<[WriteLD]>;4440 4441 def : InstAlias<asm # "\t$Rt, [$Rn]",4442 (!cast<Instruction>(NAME # "i") prfop:$Rt, GPR64sp:$Rn, 0)>;4443}4444 4445//---4446// Load/store unscaled immediate, unprivileged4447//---4448 4449class BaseLoadStoreUnprivileged<bits<2> sz, bit V, bits<2> opc,4450 dag oops, dag iops, string asm>4451 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]", "", []> {4452 bits<5> Rt;4453 bits<5> Rn;4454 bits<9> offset;4455 let Inst{31-30} = sz;4456 let Inst{29-27} = 0b111;4457 let Inst{26} = V;4458 let Inst{25-24} = 0b00;4459 let Inst{23-22} = opc;4460 let Inst{21} = 0;4461 let Inst{20-12} = offset;4462 let Inst{11-10} = 0b10;4463 let Inst{9-5} = Rn;4464 let Inst{4-0} = Rt;4465 4466 let DecoderMethod = "DecodeSignedLdStInstruction";4467}4468 4469multiclass LoadUnprivileged<bits<2> sz, bit V, bits<2> opc,4470 RegisterClass regtype, string asm> {4471 let mayStore = 0, mayLoad = 1, hasSideEffects = 0 in4472 def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs regtype:$Rt),4473 (ins GPR64sp:$Rn, simm9:$offset), asm>,4474 Sched<[WriteLD]>;4475 4476 def : InstAlias<asm # "\t$Rt, [$Rn]",4477 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;4478}4479 4480multiclass StoreUnprivileged<bits<2> sz, bit V, bits<2> opc,4481 RegisterClass regtype, string asm> {4482 let mayStore = 1, mayLoad = 0, hasSideEffects = 0 in4483 def i : BaseLoadStoreUnprivileged<sz, V, opc, (outs),4484 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),4485 asm>,4486 Sched<[WriteST]>;4487 4488 def : InstAlias<asm # "\t$Rt, [$Rn]",4489 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;4490}4491 4492//---4493// Load/store pre-indexed4494//---4495 4496class BaseLoadStorePreIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,4497 string asm, string cstr, list<dag> pat>4498 : I<oops, iops, asm, "\t$Rt, [$Rn, $offset]!", cstr, pat> {4499 bits<5> Rt;4500 bits<5> Rn;4501 bits<9> offset;4502 let Inst{31-30} = sz;4503 let Inst{29-27} = 0b111;4504 let Inst{26} = V;4505 let Inst{25-24} = 0;4506 let Inst{23-22} = opc;4507 let Inst{21} = 0;4508 let Inst{20-12} = offset;4509 let Inst{11-10} = 0b11;4510 let Inst{9-5} = Rn;4511 let Inst{4-0} = Rt;4512 4513 let DecoderMethod = "DecodeSignedLdStInstruction";4514}4515 4516let hasSideEffects = 0 in {4517let mayStore = 0, mayLoad = 1 in4518class LoadPreIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,4519 string asm>4520 : BaseLoadStorePreIdx<sz, V, opc,4521 (outs GPR64sp:$wback, regtype:$Rt),4522 (ins GPR64sp:$Rn, simm9:$offset), asm,4523 "$Rn = $wback,@earlyclobber $wback", []>,4524 Sched<[WriteAdr, WriteLD]>;4525 4526let mayStore = 1, mayLoad = 0 in4527class StorePreIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,4528 string asm, SDPatternOperator storeop, ValueType Ty>4529 : BaseLoadStorePreIdx<sz, V, opc,4530 (outs GPR64sp:$wback),4531 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),4532 asm, "$Rn = $wback,@earlyclobber $wback",4533 [(set GPR64sp:$wback,4534 (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>,4535 Sched<[WriteAdr, WriteST]>;4536} // hasSideEffects = 04537 4538//---4539// Load/store post-indexed4540//---4541 4542class BaseLoadStorePostIdx<bits<2> sz, bit V, bits<2> opc, dag oops, dag iops,4543 string asm, string cstr, list<dag> pat>4544 : I<oops, iops, asm, "\t$Rt, [$Rn], $offset", cstr, pat> {4545 bits<5> Rt;4546 bits<5> Rn;4547 bits<9> offset;4548 let Inst{31-30} = sz;4549 let Inst{29-27} = 0b111;4550 let Inst{26} = V;4551 let Inst{25-24} = 0b00;4552 let Inst{23-22} = opc;4553 let Inst{21} = 0b0;4554 let Inst{20-12} = offset;4555 let Inst{11-10} = 0b01;4556 let Inst{9-5} = Rn;4557 let Inst{4-0} = Rt;4558 4559 let DecoderMethod = "DecodeSignedLdStInstruction";4560}4561 4562let hasSideEffects = 0 in {4563let mayStore = 0, mayLoad = 1 in4564class LoadPostIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,4565 string asm>4566 : BaseLoadStorePostIdx<sz, V, opc,4567 (outs GPR64sp:$wback, regtype:$Rt),4568 (ins GPR64sp:$Rn, simm9:$offset),4569 asm, "$Rn = $wback,@earlyclobber $wback", []>,4570 Sched<[WriteAdr, WriteLD]>;4571 4572let mayStore = 1, mayLoad = 0 in4573class StorePostIdx<bits<2> sz, bit V, bits<2> opc, RegisterOperand regtype,4574 string asm, SDPatternOperator storeop, ValueType Ty>4575 : BaseLoadStorePostIdx<sz, V, opc,4576 (outs GPR64sp:$wback),4577 (ins regtype:$Rt, GPR64sp:$Rn, simm9:$offset),4578 asm, "$Rn = $wback,@earlyclobber $wback",4579 [(set GPR64sp:$wback,4580 (storeop (Ty regtype:$Rt), GPR64sp:$Rn, simm9:$offset))]>,4581 Sched<[WriteAdr, WriteST]>;4582} // hasSideEffects = 04583 4584 4585//---4586// Load/store pair4587//---4588 4589// (indexed, offset)4590 4591class BaseLoadStorePairOffset<bits<2> opc, bit V, bit L, dag oops, dag iops,4592 string asm>4593 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> {4594 bits<5> Rt;4595 bits<5> Rt2;4596 bits<5> Rn;4597 bits<7> offset;4598 let Inst{31-30} = opc;4599 let Inst{29-27} = 0b101;4600 let Inst{26} = V;4601 let Inst{25-23} = 0b010;4602 let Inst{22} = L;4603 let Inst{21-15} = offset;4604 let Inst{14-10} = Rt2;4605 let Inst{9-5} = Rn;4606 let Inst{4-0} = Rt;4607 4608 let DecoderMethod = "DecodePairLdStInstruction";4609}4610 4611multiclass LoadPairOffset<bits<2> opc, bit V, RegisterOperand regtype,4612 Operand indextype, string asm> {4613 let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in4614 def i : BaseLoadStorePairOffset<opc, V, 1,4615 (outs regtype:$Rt, regtype:$Rt2),4616 (ins GPR64sp:$Rn, indextype:$offset), asm>,4617 Sched<[WriteLD, WriteLDHi]>;4618 4619 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",4620 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,4621 GPR64sp:$Rn, 0)>;4622}4623 4624 4625multiclass StorePairOffset<bits<2> opc, bit V, RegisterOperand regtype,4626 Operand indextype, string asm> {4627 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in4628 def i : BaseLoadStorePairOffset<opc, V, 0, (outs),4629 (ins regtype:$Rt, regtype:$Rt2,4630 GPR64sp:$Rn, indextype:$offset),4631 asm>,4632 Sched<[WriteSTP]>;4633 4634 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",4635 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,4636 GPR64sp:$Rn, 0)>;4637}4638 4639class BaseLoadStoreAcquirePairOffset<bits<4> opc, bit L, dag oops, dag iops,4640 string asm>4641 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, #0]", "", []> {4642 bits<5> Rt;4643 bits<5> Rt2;4644 bits<5> Rn;4645 let Inst{31-23} = 0b110110010;4646 let Inst{22} = L;4647 let Inst{21} = 0b0;4648 let Inst{20-16} = Rt2;4649 let Inst{15-12} = opc;4650 let Inst{11-10} = 0b10;4651 let Inst{9-5} = Rn;4652 let Inst{4-0} = Rt;4653}4654 4655multiclass LoadAcquirePairOffset<bits<4> opc, string asm> {4656 let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in4657 def i : BaseLoadStoreAcquirePairOffset<opc, 0b1,4658 (outs GPR64:$Rt, GPR64:$Rt2),4659 (ins GPR64sp:$Rn), asm>,4660 Sched<[WriteAtomic, WriteLDHi]>;4661 4662 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",4663 (!cast<Instruction>(NAME # "i") GPR64:$Rt, GPR64:$Rt2,4664 GPR64sp:$Rn)>;4665}4666 4667 4668multiclass StoreAcquirePairOffset<bits<4> opc, string asm> {4669 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in4670 def i : BaseLoadStoreAcquirePairOffset<opc, 0b0, (outs),4671 (ins GPR64:$Rt, GPR64:$Rt2,4672 GPR64sp:$Rn),4673 asm>,4674 Sched<[WriteSTP]>;4675 4676 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",4677 (!cast<Instruction>(NAME # "i") GPR64:$Rt, GPR64:$Rt2,4678 GPR64sp:$Rn)>;4679}4680 4681// (pre-indexed)4682class BaseLoadStorePairPreIdx<bits<2> opc, bit V, bit L, dag oops, dag iops,4683 string asm>4684 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]!", "$Rn = $wback,@earlyclobber $wback", []> {4685 bits<5> Rt;4686 bits<5> Rt2;4687 bits<5> Rn;4688 bits<7> offset;4689 let Inst{31-30} = opc;4690 let Inst{29-27} = 0b101;4691 let Inst{26} = V;4692 let Inst{25-23} = 0b011;4693 let Inst{22} = L;4694 let Inst{21-15} = offset;4695 let Inst{14-10} = Rt2;4696 let Inst{9-5} = Rn;4697 let Inst{4-0} = Rt;4698 4699 let DecoderMethod = "DecodePairLdStInstruction";4700}4701 4702let hasSideEffects = 0 in {4703let mayStore = 0, mayLoad = 1 in4704class LoadPairPreIdx<bits<2> opc, bit V, RegisterOperand regtype,4705 Operand indextype, string asm>4706 : BaseLoadStorePairPreIdx<opc, V, 1,4707 (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2),4708 (ins GPR64sp:$Rn, indextype:$offset), asm>,4709 Sched<[WriteAdr, WriteLD, WriteLDHi]>;4710 4711let mayStore = 1, mayLoad = 0 in4712class StorePairPreIdx<bits<2> opc, bit V, RegisterOperand regtype,4713 Operand indextype, string asm>4714 : BaseLoadStorePairPreIdx<opc, V, 0, (outs GPR64sp:$wback),4715 (ins regtype:$Rt, regtype:$Rt2,4716 GPR64sp:$Rn, indextype:$offset),4717 asm>,4718 Sched<[WriteAdr, WriteSTP]>;4719} // hasSideEffects = 04720 4721// (post-indexed)4722 4723class BaseLoadStorePairPostIdx<bits<2> opc, bit V, bit L, dag oops, dag iops,4724 string asm>4725 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn], $offset", "$Rn = $wback,@earlyclobber $wback", []> {4726 bits<5> Rt;4727 bits<5> Rt2;4728 bits<5> Rn;4729 bits<7> offset;4730 let Inst{31-30} = opc;4731 let Inst{29-27} = 0b101;4732 let Inst{26} = V;4733 let Inst{25-23} = 0b001;4734 let Inst{22} = L;4735 let Inst{21-15} = offset;4736 let Inst{14-10} = Rt2;4737 let Inst{9-5} = Rn;4738 let Inst{4-0} = Rt;4739 4740 let DecoderMethod = "DecodePairLdStInstruction";4741}4742 4743let hasSideEffects = 0 in {4744let mayStore = 0, mayLoad = 1 in4745class LoadPairPostIdx<bits<2> opc, bit V, RegisterOperand regtype,4746 Operand idxtype, string asm>4747 : BaseLoadStorePairPostIdx<opc, V, 1,4748 (outs GPR64sp:$wback, regtype:$Rt, regtype:$Rt2),4749 (ins GPR64sp:$Rn, idxtype:$offset), asm>,4750 Sched<[WriteAdr, WriteLD, WriteLDHi]>;4751 4752let mayStore = 1, mayLoad = 0 in4753class StorePairPostIdx<bits<2> opc, bit V, RegisterOperand regtype,4754 Operand idxtype, string asm>4755 : BaseLoadStorePairPostIdx<opc, V, 0, (outs GPR64sp:$wback),4756 (ins regtype:$Rt, regtype:$Rt2,4757 GPR64sp:$Rn, idxtype:$offset),4758 asm>,4759 Sched<[WriteAdr, WriteSTP]>;4760} // hasSideEffects = 04761 4762// (no-allocate)4763 4764class BaseLoadStorePairNoAlloc<bits<2> opc, bit V, bit L, dag oops, dag iops,4765 string asm>4766 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> {4767 bits<5> Rt;4768 bits<5> Rt2;4769 bits<5> Rn;4770 bits<7> offset;4771 let Inst{31-30} = opc;4772 let Inst{29-27} = 0b101;4773 let Inst{26} = V;4774 let Inst{25-23} = 0b000;4775 let Inst{22} = L;4776 let Inst{21-15} = offset;4777 let Inst{14-10} = Rt2;4778 let Inst{9-5} = Rn;4779 let Inst{4-0} = Rt;4780 4781 let DecoderMethod = "DecodePairLdStInstruction";4782}4783 4784multiclass LoadPairNoAlloc<bits<2> opc, bit V, DAGOperand regtype,4785 Operand indextype, string asm> {4786 let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in4787 def i : BaseLoadStorePairNoAlloc<opc, V, 1,4788 (outs regtype:$Rt, regtype:$Rt2),4789 (ins GPR64sp:$Rn, indextype:$offset), asm>,4790 Sched<[WriteLD, WriteLDHi]>;4791 4792 4793 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",4794 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,4795 GPR64sp:$Rn, 0)>;4796}4797 4798multiclass StorePairNoAlloc<bits<2> opc, bit V, DAGOperand regtype,4799 Operand indextype, string asm> {4800 let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in4801 def i : BaseLoadStorePairNoAlloc<opc, V, 0, (outs),4802 (ins regtype:$Rt, regtype:$Rt2,4803 GPR64sp:$Rn, indextype:$offset),4804 asm>,4805 Sched<[WriteSTP]>;4806 4807 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",4808 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,4809 GPR64sp:$Rn, 0)>;4810}4811 4812// armv9.6-a load/store no-allocate pair FEAT_LSUI (no-allocate)4813 4814class BaseLoadStorePairNoAllocLSUI<bits<2> opc, bit V, bit L, dag oops, dag iops,4815 string asm>4816 : I<oops, iops, asm, "\t$Rt, $Rt2, [$Rn, $offset]", "", []> {4817 bits<5> Rt;4818 bits<5> Rt2;4819 bits<5> Rn;4820 bits<7> offset;4821 let Inst{31-30} = opc;4822 let Inst{29-27} = 0b101;4823 let Inst{26} = V;4824 let Inst{25-23} = 0b000;4825 let Inst{22} = L;4826 let Inst{21-15} = offset;4827 let Inst{14-10} = Rt2;4828 let Inst{9-5} = Rn;4829 let Inst{4-0} = Rt;4830 4831 let DecoderMethod = "DecodePairLdStInstruction";4832}4833 4834multiclass LoadPairNoAllocLSUI<bits<2> opc, bit V, DAGOperand regtype,4835 Operand indextype, string asm> {4836 let hasSideEffects = 0, mayStore = 0, mayLoad = 1 in4837 def i : BaseLoadStorePairNoAllocLSUI<opc, V, 1,4838 (outs regtype:$Rt, regtype:$Rt2),4839 (ins GPR64sp:$Rn, indextype:$offset), asm>,4840 Sched<[WriteLD, WriteLDHi]>;4841 4842 4843 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",4844 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,4845 GPR64sp:$Rn, 0)>;4846}4847 4848multiclass StorePairNoAllocLSUI<bits<2> opc, bit V, DAGOperand regtype,4849 Operand indextype, string asm> {4850 let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in4851 def i : BaseLoadStorePairNoAllocLSUI<opc, V, 0, (outs),4852 (ins regtype:$Rt, regtype:$Rt2,4853 GPR64sp:$Rn, indextype:$offset),4854 asm>,4855 Sched<[WriteSTP]>;4856 4857 def : InstAlias<asm # "\t$Rt, $Rt2, [$Rn]",4858 (!cast<Instruction>(NAME # "i") regtype:$Rt, regtype:$Rt2,4859 GPR64sp:$Rn, 0)>;4860}4861 4862//---4863// Load/store exclusive4864//---4865 4866// True exclusive operations write to and/or read from the system's exclusive4867// monitors, which as far as a compiler is concerned can be modelled as a4868// random shared memory address. Hence LoadExclusive mayStore.4869//4870// Since these instructions have the undefined register bits set to 1 in4871// their canonical form, we need a post encoder method to set those bits4872// to 1 when encoding these instructions. We do this using the4873// fixLoadStoreExclusive function. This function has template parameters:4874//4875// fixLoadStoreExclusive<int hasRs, int hasRt2>4876//4877// hasRs indicates that the instruction uses the Rs field, so we won't set4878// it to 1 (and the same for Rt2). We don't need template parameters for4879// the other register fields since Rt and Rn are always used.4880//4881let hasSideEffects = 1, mayLoad = 1, mayStore = 1 in4882class BaseLoadStoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0,4883 dag oops, dag iops, string asm, string operands>4884 : I<oops, iops, asm, operands, "", []> {4885 let Inst{31-30} = sz;4886 let Inst{29-24} = 0b001000;4887 let Inst{23} = o2;4888 let Inst{22} = L;4889 let Inst{21} = o1;4890 let Inst{15} = o0;4891 4892 let DecoderMethod = "DecodeExclusiveLdStInstruction";4893}4894 4895// Neither Rs nor Rt2 operands.4896class LoadStoreExclusiveSimple<bits<2> sz, bit o2, bit L, bit o1, bit o0,4897 dag oops, dag iops, string asm, string operands>4898 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, oops, iops, asm, operands> {4899 bits<5> Rt;4900 bits<5> Rn;4901 let Inst{20-16} = 0b11111;4902 let Unpredictable{20-16} = 0b11111;4903 let Inst{14-10} = 0b11111;4904 let Unpredictable{14-10} = 0b11111;4905 let Inst{9-5} = Rn;4906 let Inst{4-0} = Rt;4907 4908 let PostEncoderMethod = "fixLoadStoreExclusive<0,0>";4909}4910 4911// Simple load acquires don't set the exclusive monitor4912let mayLoad = 1, mayStore = 0 in4913class LoadAcquire<bits<2> sz, bit o2, bit L, bit o1, bit o0,4914 RegisterClass regtype, string asm>4915 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt),4916 (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">,4917 Sched<[WriteLD]>;4918 4919class LoadExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0,4920 RegisterClass regtype, string asm>4921 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs regtype:$Rt),4922 (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">,4923 Sched<[WriteLD]>;4924 4925class LoadExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0,4926 RegisterClass regtype, string asm>4927 : BaseLoadStoreExclusive<sz, o2, L, o1, o0,4928 (outs regtype:$Rt, regtype:$Rt2),4929 (ins GPR64sp0:$Rn), asm,4930 "\t$Rt, $Rt2, [$Rn]">,4931 Sched<[WriteLD, WriteLDHi]> {4932 bits<5> Rt;4933 bits<5> Rt2;4934 bits<5> Rn;4935 let Inst{20-16} = 0b11111;4936 let Unpredictable{20-16} = 0b11111;4937 let Inst{14-10} = Rt2;4938 let Inst{9-5} = Rn;4939 let Inst{4-0} = Rt;4940 4941 let PostEncoderMethod = "fixLoadStoreExclusive<0,1>";4942}4943 4944// Armv9.6-a load-store exclusive instructions4945let hasSideEffects = 1, mayLoad = 1, mayStore = 1 in4946class BaseLoadStoreExclusiveLSUI<bits<2> sz, bit L, bit o0,4947 dag oops, dag iops, string asm, string operands>4948 : I<oops, iops, asm, operands, "", []> {4949 let Inst{31-30} = sz;4950 let Inst{29-23} = 0b0010010;4951 let Inst{22} = L;4952 let Inst{21} = 0b0;4953 let Inst{15} = o0;4954}4955 4956 4957// Neither Rs nor Rt2 operands.4958 4959class LoadExclusiveLSUI<bits<2> sz, bit L, bit o0,4960 RegisterClass regtype, string asm>4961 : BaseLoadStoreExclusiveLSUI<sz, L, o0, (outs regtype:$Rt),4962 (ins GPR64sp0:$Rn), asm, "\t$Rt, [$Rn]">,4963 Sched<[WriteLD]>4964{4965 bits<5> Rt;4966 bits<5> Rn;4967 let Inst{20-16} = 0b11111;4968 let Unpredictable{20-16} = 0b11111;4969 let Inst{14-10} = 0b11111;4970 let Unpredictable{14-10} = 0b11111;4971 let Inst{9-5} = Rn;4972 let Inst{4-0} = Rt;4973 4974 let PostEncoderMethod = "fixLoadStoreExclusive<0,0>";4975}4976 4977 class StoreExclusiveLSUI<bits<2> sz, bit L, bit o0,4978 RegisterClass regtype, string asm>4979 : BaseLoadStoreExclusiveLSUI<sz, L, o0, (outs GPR32:$Ws),4980 (ins regtype:$Rt, GPR64sp0:$Rn),4981 asm, "\t$Ws, $Rt, [$Rn]">,4982 Sched<[WriteSTX]> {4983 bits<5> Ws;4984 bits<5> Rt;4985 bits<5> Rn;4986 let Inst{20-16} = Ws;4987 let Inst{15} = o0;4988 let Inst{14-10} = 0b11111;4989 let Unpredictable{14-10} = 0b11111;4990 let Inst{9-5} = Rn;4991 let Inst{4-0} = Rt;4992 4993 let Constraints = "@earlyclobber $Ws";4994 let PostEncoderMethod = "fixLoadStoreExclusive<1,0>";4995 }4996 4997// Armv9.6-a load-store unprivileged instructions4998class BaseLoadUnprivilegedLSUI<bits<2> sz, dag oops, dag iops, string asm>4999 : I<oops, iops, asm, "\t$Rt, [$Rn]", "", []> {5000 bits<5> Rt;5001 bits<5> Rn;5002 let Inst{31-30} = sz;5003 let Inst{29-23} = 0b0010010;5004 let Inst{22} = 0b1;5005 let Inst{21} = 0b0;5006 let Inst{20-16} = 0b11111;5007 let Unpredictable{20-16} = 0b11111;5008 let Inst{15} = 0b0;5009 let Inst{14-10} = 0b11111;5010 let Unpredictable{14-10} = 0b11111;5011 let Inst{9-5} = Rn;5012 let Inst{4-0} = Rt;5013 let PostEncoderMethod = "fixLoadStoreExclusive<0,0>";5014}5015 5016multiclass LoadUnprivilegedLSUI<bits<2> sz, RegisterClass regtype, string asm> {5017 def r : BaseLoadUnprivilegedLSUI<sz, (outs regtype:$Rt),5018 (ins GPR64sp0:$Rn), asm>,5019 Sched<[WriteLD]>;5020 5021}5022 5023class BaseStoreUnprivilegedLSUI<bits<2> sz, dag oops, dag iops, string asm>5024 : I<oops, iops, asm, "\t$Ws, $Rt, [$Rn]", "", []> {5025 bits<5> Rt;5026 bits<5> Rn;5027 bits<5> Ws;5028 let Inst{31-30} = sz;5029 let Inst{29-23} = 0b0010010;5030 let Inst{22} = 0b0;5031 let Inst{21} = 0b0;5032 let Inst{20-16} = Ws;5033 let Inst{15} = 0b0;5034 let Inst{14-10} = 0b11111;5035 let Unpredictable{14-10} = 0b11111;5036 let Inst{9-5} = Rn;5037 let Inst{4-0} = Rt;5038 let PostEncoderMethod = "fixLoadStoreExclusive<1,0>";5039 let mayStore = 1;5040}5041 5042multiclass StoreUnprivilegedLSUI<bits<2> sz, RegisterClass regtype, string asm> {5043 def r : BaseStoreUnprivilegedLSUI<sz, (outs GPR32: $Ws),5044 (ins regtype:$Rt, GPR64sp0:$Rn),5045 asm>,5046 Sched<[WriteSTX]>;5047}5048 5049// Simple store release operations do not check the exclusive monitor.5050let mayLoad = 0, mayStore = 1 in5051class StoreRelease<bits<2> sz, bit o2, bit L, bit o1, bit o0,5052 RegisterClass regtype, string asm>5053 : LoadStoreExclusiveSimple<sz, o2, L, o1, o0, (outs),5054 (ins regtype:$Rt, GPR64sp:$Rn),5055 asm, "\t$Rt, [$Rn]">,5056 Sched<[WriteST]>;5057 5058let mayLoad = 1, mayStore = 1 in5059class StoreExclusive<bits<2> sz, bit o2, bit L, bit o1, bit o0,5060 RegisterClass regtype, string asm>5061 : BaseLoadStoreExclusive<sz, o2, L, o1, o0, (outs GPR32:$Ws),5062 (ins regtype:$Rt, GPR64sp0:$Rn),5063 asm, "\t$Ws, $Rt, [$Rn]">,5064 Sched<[WriteSTX]> {5065 bits<5> Ws;5066 bits<5> Rt;5067 bits<5> Rn;5068 let Inst{20-16} = Ws;5069 let Inst{9-5} = Rn;5070 let Inst{4-0} = Rt;5071 5072 let Constraints = "@earlyclobber $Ws";5073 let PostEncoderMethod = "fixLoadStoreExclusive<1,0>";5074}5075 5076class StoreExclusivePair<bits<2> sz, bit o2, bit L, bit o1, bit o0,5077 RegisterClass regtype, string asm>5078 : BaseLoadStoreExclusive<sz, o2, L, o1, o0,5079 (outs GPR32:$Ws),5080 (ins regtype:$Rt, regtype:$Rt2, GPR64sp0:$Rn),5081 asm, "\t$Ws, $Rt, $Rt2, [$Rn]">,5082 Sched<[WriteSTX]> {5083 bits<5> Ws;5084 bits<5> Rt;5085 bits<5> Rt2;5086 bits<5> Rn;5087 let Inst{20-16} = Ws;5088 let Inst{14-10} = Rt2;5089 let Inst{9-5} = Rn;5090 let Inst{4-0} = Rt;5091 5092 let Constraints = "@earlyclobber $Ws";5093}5094 5095// Armv8.5-A Memory Tagging Extension5096class BaseMemTag<bits<2> opc1, bits<2> opc2, string asm_insn,5097 string asm_opnds, string cstr, dag oops, dag iops>5098 : I<oops, iops, asm_insn, asm_opnds, cstr, []>,5099 Sched<[]> {5100 bits<5> Rn;5101 5102 let Inst{31-24} = 0b11011001;5103 let Inst{23-22} = opc1;5104 let Inst{21} = 1;5105 // Inst{20-12} defined by subclass5106 let Inst{11-10} = opc2;5107 let Inst{9-5} = Rn;5108 // Inst{4-0} defined by subclass5109}5110 5111class MemTagVector<bit Load, string asm_insn, string asm_opnds,5112 dag oops, dag iops>5113 : BaseMemTag<{0b1, Load}, 0b00, asm_insn, asm_opnds,5114 "", oops, iops> {5115 bits<5> Rt;5116 5117 let Inst{20-12} = 0b000000000;5118 let Inst{4-0} = Rt;5119 5120 let mayLoad = Load;5121}5122 5123class MemTagLoad<string asm_insn, string asm_opnds>5124 : BaseMemTag<0b01, 0b00, asm_insn, asm_opnds, "$Rt = $wback",5125 (outs GPR64:$wback),5126 (ins GPR64:$Rt, GPR64sp:$Rn, simm9s16:$offset)> {5127 bits<5> Rt;5128 bits<9> offset;5129 5130 let Inst{20-12} = offset;5131 let Inst{4-0} = Rt;5132 5133 let mayLoad = 1;5134}5135 5136class BaseMemTagStore<bits<2> opc1, bits<2> opc2, string asm_insn,5137 string asm_opnds, string cstr, dag oops, dag iops>5138 : BaseMemTag<opc1, opc2, asm_insn, asm_opnds, cstr, oops, iops> {5139 bits<5> Rt;5140 bits<9> offset;5141 5142 let Inst{20-12} = offset;5143 let Inst{4-0} = Rt;5144 5145 let mayStore = 1;5146}5147 5148multiclass MemTagStore<bits<2> opc1, string insn> {5149 def i :5150 BaseMemTagStore<opc1, 0b10, insn, "\t$Rt, [$Rn, $offset]", "",5151 (outs), (ins GPR64sp:$Rt, GPR64sp:$Rn, simm9s16:$offset)>;5152 def PreIndex :5153 BaseMemTagStore<opc1, 0b11, insn, "\t$Rt, [$Rn, $offset]!",5154 "$Rn = $wback",5155 (outs GPR64sp:$wback),5156 (ins GPR64sp:$Rt, GPR64sp:$Rn, simm9s16:$offset)>;5157 def PostIndex :5158 BaseMemTagStore<opc1, 0b01, insn, "\t$Rt, [$Rn], $offset",5159 "$Rn = $wback",5160 (outs GPR64sp:$wback),5161 (ins GPR64sp:$Rt, GPR64sp:$Rn, simm9s16:$offset)>;5162 5163 def : InstAlias<insn # "\t$Rt, [$Rn]",5164 (!cast<Instruction>(NAME # "i") GPR64sp:$Rt, GPR64sp:$Rn, 0)>;5165}5166 5167//---5168// Exception generation5169//---5170 5171let mayLoad = 0, mayStore = 0, hasSideEffects = 1 in5172class ExceptionGeneration<bits<3> op1, bits<2> ll, string asm,5173 list<dag> pattern = []>5174 : I<(outs), (ins timm32_0_65535:$imm), asm, "\t$imm", "", pattern>,5175 Sched<[WriteSys]> {5176 bits<16> imm;5177 let Inst{31-24} = 0b11010100;5178 let Inst{23-21} = op1;5179 let Inst{20-5} = imm;5180 let Inst{4-2} = 0b000;5181 let Inst{1-0} = ll;5182}5183 5184//---5185// UDF : Permanently UNDEFINED instructions. Format: Opc = 0x0000, 16 bit imm.5186//--5187let hasSideEffects = 1, isTrap = 1, mayLoad = 0, mayStore = 0 in {5188class UDFType<bits<16> opc, string asm>5189 : I<(outs), (ins uimm16:$imm),5190 asm, "\t$imm", "", []>,5191 Sched<[]> {5192 bits<16> imm;5193 let Inst{31-16} = opc;5194 let Inst{15-0} = imm;5195}5196}5197let Predicates = [HasFPARMv8] in {5198 5199//---5200// Floating point to integer conversion5201//---5202 5203let mayRaiseFPException = 1, Uses = [FPCR] in5204class BaseFPToIntegerUnscaled<bits<2> type, bits<2> rmode, bits<3> opcode,5205 RegisterClass srcType, RegisterClass dstType,5206 string asm, list<dag> pattern>5207 : I<(outs dstType:$Rd), (ins srcType:$Rn),5208 asm, "\t$Rd, $Rn", "", pattern>,5209 Sched<[WriteFCvt]> {5210 bits<5> Rd;5211 bits<5> Rn;5212 let Inst{30-29} = 0b00;5213 let Inst{28-24} = 0b11110;5214 let Inst{23-22} = type;5215 let Inst{21} = 1;5216 let Inst{20-19} = rmode;5217 let Inst{18-16} = opcode;5218 let Inst{15-10} = 0;5219 let Inst{9-5} = Rn;5220 let Inst{4-0} = Rd;5221}5222 5223let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in5224class BaseFPToInteger<bits<2> type, bits<2> rmode, bits<3> opcode,5225 RegisterClass srcType, RegisterClass dstType,5226 Operand immType, string asm, list<dag> pattern>5227 : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale),5228 asm, "\t$Rd, $Rn, $scale", "", pattern>,5229 Sched<[WriteFCvt]> {5230 bits<5> Rd;5231 bits<5> Rn;5232 bits<6> scale;5233 let Inst{30-29} = 0b00;5234 let Inst{28-24} = 0b11110;5235 let Inst{23-22} = type;5236 let Inst{21} = 0;5237 let Inst{20-19} = rmode;5238 let Inst{18-16} = opcode;5239 let Inst{15-10} = scale;5240 let Inst{9-5} = Rn;5241 let Inst{4-0} = Rd;5242}5243 5244multiclass FPToIntegerUnscaled<bits<2> rmode, bits<3> opcode, string asm,5245 SDPatternOperator OpN> {5246 // Unscaled half-precision to 32-bit5247 def UWHr : BaseFPToIntegerUnscaled<0b11, rmode, opcode, FPR16, GPR32, asm,5248 [(set GPR32:$Rd, (OpN (f16 FPR16:$Rn)))]> {5249 let Inst{31} = 0; // 32-bit GPR flag5250 let Predicates = [HasFullFP16];5251 }5252 5253 // Unscaled half-precision to 64-bit5254 def UXHr : BaseFPToIntegerUnscaled<0b11, rmode, opcode, FPR16, GPR64, asm,5255 [(set GPR64:$Rd, (OpN (f16 FPR16:$Rn)))]> {5256 let Inst{31} = 1; // 64-bit GPR flag5257 let Predicates = [HasFullFP16];5258 }5259 5260 // Unscaled single-precision to 32-bit5261 def UWSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR32, asm,5262 [(set GPR32:$Rd, (OpN FPR32:$Rn))]> {5263 let Inst{31} = 0; // 32-bit GPR flag5264 }5265 5266 // Unscaled single-precision to 64-bit5267 def UXSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, GPR64, asm,5268 [(set GPR64:$Rd, (OpN FPR32:$Rn))]> {5269 let Inst{31} = 1; // 64-bit GPR flag5270 }5271 5272 // Unscaled double-precision to 32-bit5273 def UWDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR32, asm,5274 [(set GPR32:$Rd, (OpN (f64 FPR64:$Rn)))]> {5275 let Inst{31} = 0; // 32-bit GPR flag5276 }5277 5278 // Unscaled double-precision to 64-bit5279 def UXDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, GPR64, asm,5280 [(set GPR64:$Rd, (OpN (f64 FPR64:$Rn)))]> {5281 let Inst{31} = 1; // 64-bit GPR flag5282 }5283}5284 5285multiclass FPToIntegerSIMDScalar<bits<2> rmode, bits<3> opcode, string asm, 5286 SDPatternOperator OpN> {5287 // double-precision to 32-bit SIMD/FPR5288 def SDr : BaseFPToIntegerUnscaled<0b01, rmode, opcode, FPR64, FPR32, asm,5289 [(set FPR32:$Rd, (i32 (OpN (f64 FPR64:$Rn))))]> {5290 let Inst{31} = 0; // 32-bit FPR flag5291 }5292 5293 // half-precision to 32-bit SIMD/FPR5294 def SHr : BaseFPToIntegerUnscaled<0b11, rmode, opcode, FPR16, FPR32, asm,5295 [(set FPR32:$Rd, (i32 (OpN (f16 FPR16:$Rn))))]> {5296 let Inst{31} = 0; // 32-bit FPR flag5297 }5298 5299 // half-precision to 64-bit SIMD/FPR5300 def DHr : BaseFPToIntegerUnscaled<0b11, rmode, opcode, FPR16, FPR64, asm,5301 [(set FPR64:$Rd, (i64 (OpN (f16 FPR16:$Rn))))]> {5302 let Inst{31} = 1; // 64-bit FPR flag5303 }5304 5305 // single-precision to 64-bit SIMD/FPR5306 def DSr : BaseFPToIntegerUnscaled<0b00, rmode, opcode, FPR32, FPR64, asm,5307 [(set FPR64:$Rd, (i64 (OpN (f32 FPR32:$Rn))))]> {5308 let Inst{31} = 1; // 64-bit FPR flag5309 }5310}5311 5312multiclass FPToIntegerScaled<bits<2> rmode, bits<3> opcode, string asm,5313 SDPatternOperator OpN> {5314 // Scaled half-precision to 32-bit5315 def SWHri : BaseFPToInteger<0b11, rmode, opcode, FPR16, GPR32,5316 fixedpoint_f16_i32, asm,5317 [(set GPR32:$Rd, (OpN (fmul (f16 FPR16:$Rn),5318 fixedpoint_f16_i32:$scale)))]> {5319 let Inst{31} = 0; // 32-bit GPR flag5320 let scale{5} = 1;5321 let Predicates = [HasFullFP16];5322 }5323 5324 // Scaled half-precision to 64-bit5325 def SXHri : BaseFPToInteger<0b11, rmode, opcode, FPR16, GPR64,5326 fixedpoint_f16_i64, asm,5327 [(set GPR64:$Rd, (OpN (fmul (f16 FPR16:$Rn),5328 fixedpoint_f16_i64:$scale)))]> {5329 let Inst{31} = 1; // 64-bit GPR flag5330 let Predicates = [HasFullFP16];5331 }5332 5333 // Scaled single-precision to 32-bit5334 def SWSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR32,5335 fixedpoint_f32_i32, asm,5336 [(set GPR32:$Rd, (OpN (fmul FPR32:$Rn,5337 fixedpoint_f32_i32:$scale)))]> {5338 let Inst{31} = 0; // 32-bit GPR flag5339 let scale{5} = 1;5340 }5341 5342 // Scaled single-precision to 64-bit5343 def SXSri : BaseFPToInteger<0b00, rmode, opcode, FPR32, GPR64,5344 fixedpoint_f32_i64, asm,5345 [(set GPR64:$Rd, (OpN (fmul FPR32:$Rn,5346 fixedpoint_f32_i64:$scale)))]> {5347 let Inst{31} = 1; // 64-bit GPR flag5348 }5349 5350 // Scaled double-precision to 32-bit5351 def SWDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR32,5352 fixedpoint_f64_i32, asm,5353 [(set GPR32:$Rd, (OpN (fmul FPR64:$Rn,5354 fixedpoint_f64_i32:$scale)))]> {5355 let Inst{31} = 0; // 32-bit GPR flag5356 let scale{5} = 1;5357 }5358 5359 // Scaled double-precision to 64-bit5360 def SXDri : BaseFPToInteger<0b01, rmode, opcode, FPR64, GPR64,5361 fixedpoint_f64_i64, asm,5362 [(set GPR64:$Rd, (OpN (fmul FPR64:$Rn,5363 fixedpoint_f64_i64:$scale)))]> {5364 let Inst{31} = 1; // 64-bit GPR flag5365 }5366}5367 5368//---5369// Integer to floating point conversion5370//---5371 5372let mayStore = 0, mayLoad = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in5373class BaseIntegerToFP<bits<2> rmode, bits<3> opcode,5374 RegisterClass srcType, RegisterClass dstType,5375 Operand immType, string asm, list<dag> pattern>5376 : I<(outs dstType:$Rd), (ins srcType:$Rn, immType:$scale),5377 asm, "\t$Rd, $Rn, $scale", "", pattern>,5378 Sched<[WriteFCvt]> {5379 bits<5> Rd;5380 bits<5> Rn;5381 bits<6> scale;5382 let Inst{30-24} = 0b0011110;5383 let Inst{21} = 0b0;5384 let Inst{20-19} = rmode;5385 let Inst{18-16} = opcode;5386 let Inst{15-10} = scale;5387 let Inst{9-5} = Rn;5388 let Inst{4-0} = Rd;5389}5390 5391let mayRaiseFPException = 1, Uses = [FPCR] in5392class BaseIntegerToFPUnscaled<bits<2> rmode, bits<3> opcode,5393 RegisterClass srcType, RegisterClass dstType,5394 ValueType dvt, string asm, SDPatternOperator node>5395 : I<(outs dstType:$Rd), (ins srcType:$Rn),5396 asm, "\t$Rd, $Rn", "", [(set (dvt dstType:$Rd), (node srcType:$Rn))]>,5397 Sched<[WriteFCvt]> {5398 bits<5> Rd;5399 bits<5> Rn;5400 bits<6> scale;5401 let Inst{30-24} = 0b0011110;5402 let Inst{21} = 0b1;5403 let Inst{20-19} = rmode;5404 let Inst{18-16} = opcode;5405 let Inst{15-10} = 0b000000;5406 let Inst{9-5} = Rn;5407 let Inst{4-0} = Rd;5408}5409 5410multiclass IntegerToFP<bits<2> rmode, bits<3> opcode, string asm, SDPatternOperator node> {5411 // Unscaled5412 def UWHri: BaseIntegerToFPUnscaled<rmode, opcode, GPR32, FPR16, f16, asm, node> {5413 let Inst{31} = 0; // 32-bit GPR flag5414 let Inst{23-22} = 0b11; // 16-bit FPR flag5415 let Predicates = [HasFullFP16];5416 }5417 5418 def UWSri: BaseIntegerToFPUnscaled<rmode, opcode, GPR32, FPR32, f32, asm, node> {5419 let Inst{31} = 0; // 32-bit GPR flag5420 let Inst{23-22} = 0b00; // 32-bit FPR flag5421 }5422 5423 def UWDri: BaseIntegerToFPUnscaled<rmode, opcode, GPR32, FPR64, f64, asm, node> {5424 let Inst{31} = 0; // 32-bit GPR flag5425 let Inst{23-22} = 0b01; // 64-bit FPR flag5426 }5427 5428 def UXHri: BaseIntegerToFPUnscaled<rmode, opcode, GPR64, FPR16, f16, asm, node> {5429 let Inst{31} = 1; // 64-bit GPR flag5430 let Inst{23-22} = 0b11; // 16-bit FPR flag5431 let Predicates = [HasFullFP16];5432 }5433 5434 def UXSri: BaseIntegerToFPUnscaled<rmode, opcode, GPR64, FPR32, f32, asm, node> {5435 let Inst{31} = 1; // 64-bit GPR flag5436 let Inst{23-22} = 0b00; // 32-bit FPR flag5437 }5438 5439 def UXDri: BaseIntegerToFPUnscaled<rmode, opcode, GPR64, FPR64, f64, asm, node> {5440 let Inst{31} = 1; // 64-bit GPR flag5441 let Inst{23-22} = 0b01; // 64-bit FPR flag5442 }5443 5444 // Scaled5445 def SWHri: BaseIntegerToFP<rmode, opcode, GPR32, FPR16, fixedpoint_recip_f16_i32, asm,5446 [(set (f16 FPR16:$Rd),5447 (fmul (node GPR32:$Rn),5448 fixedpoint_recip_f16_i32:$scale))]> {5449 let Inst{31} = 0; // 32-bit GPR flag5450 let Inst{23-22} = 0b11; // 16-bit FPR flag5451 let scale{5} = 1;5452 let Predicates = [HasFullFP16];5453 }5454 5455 def SWSri: BaseIntegerToFP<rmode, opcode, GPR32, FPR32, fixedpoint_recip_f32_i32, asm,5456 [(set FPR32:$Rd,5457 (fmul (node GPR32:$Rn),5458 fixedpoint_recip_f32_i32:$scale))]> {5459 let Inst{31} = 0; // 32-bit GPR flag5460 let Inst{23-22} = 0b00; // 32-bit FPR flag5461 let scale{5} = 1;5462 }5463 5464 def SWDri: BaseIntegerToFP<rmode, opcode, GPR32, FPR64, fixedpoint_recip_f64_i32, asm,5465 [(set FPR64:$Rd,5466 (fmul (node GPR32:$Rn),5467 fixedpoint_recip_f64_i32:$scale))]> {5468 let Inst{31} = 0; // 32-bit GPR flag5469 let Inst{23-22} = 0b01; // 64-bit FPR flag5470 let scale{5} = 1;5471 }5472 5473 def SXHri: BaseIntegerToFP<rmode, opcode, GPR64, FPR16, fixedpoint_recip_f16_i64, asm,5474 [(set (f16 FPR16:$Rd),5475 (fmul (node GPR64:$Rn),5476 fixedpoint_recip_f16_i64:$scale))]> {5477 let Inst{31} = 1; // 64-bit GPR flag5478 let Inst{23-22} = 0b11; // 16-bit FPR flag5479 let Predicates = [HasFullFP16];5480 }5481 5482 def SXSri: BaseIntegerToFP<rmode, opcode, GPR64, FPR32, fixedpoint_recip_f32_i64, asm,5483 [(set FPR32:$Rd,5484 (fmul (node GPR64:$Rn),5485 fixedpoint_recip_f32_i64:$scale))]> {5486 let Inst{31} = 1; // 64-bit GPR flag5487 let Inst{23-22} = 0b00; // 32-bit FPR flag5488 }5489 5490 def SXDri: BaseIntegerToFP<rmode, opcode, GPR64, FPR64, fixedpoint_recip_f64_i64, asm,5491 [(set FPR64:$Rd,5492 (fmul (node GPR64:$Rn),5493 fixedpoint_recip_f64_i64:$scale))]> {5494 let Inst{31} = 1; // 64-bit GPR flag5495 let Inst{23-22} = 0b01; // 64-bit FPR flag5496 }5497}5498 5499multiclass IntegerToFPSIMDScalar<bits<2> rmode, bits<3> opcode, string asm, SDPatternOperator node = null_frag> {5500 // 32-bit to half-precision5501 def HSr: BaseIntegerToFPUnscaled<rmode, opcode, FPR32, FPR16, f16, asm, node> {5502 let Inst{31} = 0; // 32-bit FPR flag5503 let Inst{23-22} = 0b11; // 16-bit FPR flag5504 }5505 5506 // 32-bit to double-precision5507 def DSr: BaseIntegerToFPUnscaled<rmode, opcode, FPR32, FPR64, f64, asm, node> {5508 let Inst{31} = 0; // 32-bit FPR flag5509 let Inst{23-22} = 0b01; // 64-bit FPR flag5510 }5511 5512 // 64-bit to half-precision5513 def HDr: BaseIntegerToFPUnscaled<rmode, opcode, FPR64, FPR16, f16, asm, node> {5514 let Inst{31} = 1; // 64-bit FPR flag5515 let Inst{23-22} = 0b11; // 16-bit FPR flag5516 }5517 5518 // 64-bit to single-precision5519 def SDr: BaseIntegerToFPUnscaled<rmode, opcode, FPR64, FPR32, f32, asm, node> {5520 let Inst{31} = 1; // 64-bit FPR flag5521 let Inst{23-22} = 0b00; // 32-bit FPR flag5522 }5523 5524 def : Pat<(f16 (node (i32 (extractelt (v4i32 V128:$Rn), (i64 0))))),5525 (!cast<Instruction>(NAME # HSr) (EXTRACT_SUBREG V128:$Rn, ssub))>;5526 def : Pat<(f64 (node (i32 (extractelt (v4i32 V128:$Rn), (i64 0))))),5527 (!cast<Instruction>(NAME # DSr) (EXTRACT_SUBREG V128:$Rn, ssub))>;5528 def : Pat<(f16 (node (i64 (extractelt (v2i64 V128:$Rn), (i64 0))))),5529 (!cast<Instruction>(NAME # HDr) (EXTRACT_SUBREG V128:$Rn, dsub))>;5530 def : Pat<(f32 (node (i64 (extractelt (v2i64 V128:$Rn), (i64 0))))),5531 (!cast<Instruction>(NAME # SDr) (EXTRACT_SUBREG V128:$Rn, dsub))>;5532}5533 5534//---5535// Unscaled integer <-> floating point conversion (i.e. FMOV)5536//---5537 5538let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in5539class BaseUnscaledConversion<bits<2> rmode, bits<3> opcode,5540 RegisterClass srcType, RegisterClass dstType,5541 string asm>5542 : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "",5543 // We use COPY_TO_REGCLASS for these bitconvert operations.5544 // copyPhysReg() expands the resultant COPY instructions after5545 // regalloc is done. This gives greater freedom for the allocator5546 // and related passes (coalescing, copy propagation, et. al.) to5547 // be more effective.5548 [/*(set (dvt dstType:$Rd), (bitconvert (svt srcType:$Rn)))*/]>,5549 Sched<[WriteFCopy]> {5550 bits<5> Rd;5551 bits<5> Rn;5552 let Inst{30-24} = 0b0011110;5553 let Inst{21} = 1;5554 let Inst{20-19} = rmode;5555 let Inst{18-16} = opcode;5556 let Inst{15-10} = 0b000000;5557 let Inst{9-5} = Rn;5558 let Inst{4-0} = Rd;5559}5560 5561let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in5562class BaseUnscaledConversionToHigh<bits<2> rmode, bits<3> opcode,5563 RegisterClass srcType, RegisterOperand dstType, string asm,5564 string kind>5565 : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm,5566 "{\t$Rd"#kind#"$idx, $Rn|"#kind#"\t$Rd$idx, $Rn}", "", []>,5567 Sched<[WriteFCopy]> {5568 bits<5> Rd;5569 bits<5> Rn;5570 let Inst{30-23} = 0b00111101;5571 let Inst{21} = 1;5572 let Inst{20-19} = rmode;5573 let Inst{18-16} = opcode;5574 let Inst{15-10} = 0b000000;5575 let Inst{9-5} = Rn;5576 let Inst{4-0} = Rd;5577 5578 let DecoderMethod = "DecodeFMOVLaneInstruction";5579}5580 5581let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in5582class BaseUnscaledConversionFromHigh<bits<2> rmode, bits<3> opcode,5583 RegisterOperand srcType, RegisterClass dstType, string asm,5584 string kind>5585 : I<(outs dstType:$Rd), (ins srcType:$Rn, VectorIndex1:$idx), asm,5586 "{\t$Rd, $Rn"#kind#"$idx|"#kind#"\t$Rd, $Rn$idx}", "", []>,5587 Sched<[WriteFCopy]> {5588 bits<5> Rd;5589 bits<5> Rn;5590 let Inst{30-23} = 0b00111101;5591 let Inst{21} = 1;5592 let Inst{20-19} = rmode;5593 let Inst{18-16} = opcode;5594 let Inst{15-10} = 0b000000;5595 let Inst{9-5} = Rn;5596 let Inst{4-0} = Rd;5597 5598 let DecoderMethod = "DecodeFMOVLaneInstruction";5599}5600 5601 5602multiclass UnscaledConversion<string asm> {5603 def WHr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR16, asm> {5604 let Inst{31} = 0; // 32-bit GPR flag5605 let Inst{23-22} = 0b11; // 16-bit FPR flag5606 let Predicates = [HasFullFP16];5607 }5608 5609 def XHr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR16, asm> {5610 let Inst{31} = 1; // 64-bit GPR flag5611 let Inst{23-22} = 0b11; // 16-bit FPR flag5612 let Predicates = [HasFullFP16];5613 }5614 5615 def WSr : BaseUnscaledConversion<0b00, 0b111, GPR32, FPR32, asm> {5616 let Inst{31} = 0; // 32-bit GPR flag5617 let Inst{23-22} = 0b00; // 32-bit FPR flag5618 }5619 5620 def XDr : BaseUnscaledConversion<0b00, 0b111, GPR64, FPR64, asm> {5621 let Inst{31} = 1; // 64-bit GPR flag5622 let Inst{23-22} = 0b01; // 64-bit FPR flag5623 }5624 5625 def HWr : BaseUnscaledConversion<0b00, 0b110, FPR16, GPR32, asm> {5626 let Inst{31} = 0; // 32-bit GPR flag5627 let Inst{23-22} = 0b11; // 16-bit FPR flag5628 let Predicates = [HasFullFP16];5629 }5630 5631 def HXr : BaseUnscaledConversion<0b00, 0b110, FPR16, GPR64, asm> {5632 let Inst{31} = 1; // 64-bit GPR flag5633 let Inst{23-22} = 0b11; // 16-bit FPR flag5634 let Predicates = [HasFullFP16];5635 }5636 5637 def SWr : BaseUnscaledConversion<0b00, 0b110, FPR32, GPR32, asm> {5638 let Inst{31} = 0; // 32-bit GPR flag5639 let Inst{23-22} = 0b00; // 32-bit FPR flag5640 }5641 5642 def DXr : BaseUnscaledConversion<0b00, 0b110, FPR64, GPR64, asm> {5643 let Inst{31} = 1; // 64-bit GPR flag5644 let Inst{23-22} = 0b01; // 64-bit FPR flag5645 }5646 5647 def XDHighr : BaseUnscaledConversionToHigh<0b01, 0b111, GPR64, V128,5648 asm, ".d"> {5649 let Inst{31} = 1;5650 let Inst{22} = 0;5651 }5652 5653 def DXHighr : BaseUnscaledConversionFromHigh<0b01, 0b110, V128, GPR64,5654 asm, ".d"> {5655 let Inst{31} = 1;5656 let Inst{22} = 0;5657 }5658}5659 5660//---5661// Floating point conversion5662//---5663 5664let mayRaiseFPException = 1, Uses = [FPCR] in5665class BaseFPConversion<bits<2> type, bits<2> opcode, RegisterClass dstType,5666 RegisterClass srcType, string asm, list<dag> pattern>5667 : I<(outs dstType:$Rd), (ins srcType:$Rn), asm, "\t$Rd, $Rn", "", pattern>,5668 Sched<[WriteFCvt]> {5669 bits<5> Rd;5670 bits<5> Rn;5671 let Inst{31-24} = 0b00011110;5672 let Inst{23-22} = type;5673 let Inst{21-17} = 0b10001;5674 let Inst{16-15} = opcode;5675 let Inst{14-10} = 0b10000;5676 let Inst{9-5} = Rn;5677 let Inst{4-0} = Rd;5678}5679 5680multiclass FPConversion<string asm> {5681 // Double-precision to Half-precision5682 def HDr : BaseFPConversion<0b01, 0b11, FPR16, FPR64, asm,5683 [(set (f16 FPR16:$Rd), (any_fpround FPR64:$Rn))]>;5684 5685 // Double-precision to Single-precision5686 def SDr : BaseFPConversion<0b01, 0b00, FPR32, FPR64, asm,5687 [(set FPR32:$Rd, (any_fpround FPR64:$Rn))]>;5688 5689 // Half-precision to Double-precision5690 def DHr : BaseFPConversion<0b11, 0b01, FPR64, FPR16, asm,5691 [(set FPR64:$Rd, (any_fpextend (f16 FPR16:$Rn)))]>;5692 5693 // Half-precision to Single-precision5694 def SHr : BaseFPConversion<0b11, 0b00, FPR32, FPR16, asm,5695 [(set FPR32:$Rd, (any_fpextend (f16 FPR16:$Rn)))]>;5696 5697 // Single-precision to Double-precision5698 def DSr : BaseFPConversion<0b00, 0b01, FPR64, FPR32, asm,5699 [(set FPR64:$Rd, (any_fpextend FPR32:$Rn))]>;5700 5701 // Single-precision to Half-precision5702 def HSr : BaseFPConversion<0b00, 0b11, FPR16, FPR32, asm,5703 [(set (f16 FPR16:$Rd), (any_fpround FPR32:$Rn))]>;5704}5705 5706//---5707// Single operand floating point data processing5708//---5709 5710let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in5711class BaseSingleOperandFPData<bits<6> opcode, RegisterClass regtype,5712 ValueType vt, string asm, SDPatternOperator node>5713 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm, "\t$Rd, $Rn", "",5714 [(set (vt regtype:$Rd), (node (vt regtype:$Rn)))]>,5715 Sched<[WriteF]> {5716 bits<5> Rd;5717 bits<5> Rn;5718 let Inst{31-24} = 0b00011110;5719 let Inst{21} = 0b1;5720 let Inst{20-15} = opcode;5721 let Inst{14-10} = 0b10000;5722 let Inst{9-5} = Rn;5723 let Inst{4-0} = Rd;5724}5725 5726multiclass SingleOperandFPData<bits<4> opcode, string asm,5727 SDPatternOperator node = null_frag,5728 int fpexceptions = 1> {5729 let mayRaiseFPException = fpexceptions, Uses = !if(fpexceptions,[FPCR],[]<Register>) in {5730 def Hr : BaseSingleOperandFPData<{0b00,opcode}, FPR16, f16, asm, node> {5731 let Inst{23-22} = 0b11; // 16-bit size flag5732 let Predicates = [HasFullFP16];5733 }5734 5735 def Sr : BaseSingleOperandFPData<{0b00,opcode}, FPR32, f32, asm, node> {5736 let Inst{23-22} = 0b00; // 32-bit size flag5737 }5738 5739 def Dr : BaseSingleOperandFPData<{0b00,opcode}, FPR64, f64, asm, node> {5740 let Inst{23-22} = 0b01; // 64-bit size flag5741 }5742 }5743}5744 5745multiclass SingleOperandFPDataNoException<bits<4> opcode, string asm,5746 SDPatternOperator node = null_frag>5747 : SingleOperandFPData<opcode, asm, node, 0>;5748 5749let mayRaiseFPException = 1, Uses = [FPCR] in5750multiclass SingleOperandFPNo16<bits<6> opcode, string asm,5751 SDPatternOperator node = null_frag>{5752 5753 def Sr : BaseSingleOperandFPData<opcode, FPR32, f32, asm, node> {5754 let Inst{23-22} = 0b00; // 32-bit registers5755 }5756 5757 def Dr : BaseSingleOperandFPData<opcode, FPR64, f64, asm, node> {5758 let Inst{23-22} = 0b01; // 64-bit registers5759 }5760}5761 5762// FRInt[32|64][Z|N] instructions5763multiclass FRIntNNT<bits<2> opcode, string asm, SDPatternOperator node = null_frag> :5764 SingleOperandFPNo16<{0b0100,opcode}, asm, node>;5765 5766//---5767// Two operand floating point data processing5768//---5769 5770let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in5771class BaseTwoOperandFPData<bits<4> opcode, RegisterClass regtype,5772 string asm, list<dag> pat>5773 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm),5774 asm, "\t$Rd, $Rn, $Rm", "", pat>,5775 Sched<[WriteF]> {5776 bits<5> Rd;5777 bits<5> Rn;5778 bits<5> Rm;5779 let Inst{31-24} = 0b00011110;5780 let Inst{21} = 1;5781 let Inst{20-16} = Rm;5782 let Inst{15-12} = opcode;5783 let Inst{11-10} = 0b10;5784 let Inst{9-5} = Rn;5785 let Inst{4-0} = Rd;5786}5787 5788multiclass TwoOperandFPData<bits<4> opcode, string asm,5789 SDPatternOperator node = null_frag> {5790 def Hrr : BaseTwoOperandFPData<opcode, FPR16, asm,5791 [(set (f16 FPR16:$Rd),5792 (node (f16 FPR16:$Rn), (f16 FPR16:$Rm)))]> {5793 let Inst{23-22} = 0b11; // 16-bit size flag5794 let Predicates = [HasFullFP16];5795 }5796 5797 def Srr : BaseTwoOperandFPData<opcode, FPR32, asm,5798 [(set (f32 FPR32:$Rd),5799 (node (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]> {5800 let Inst{23-22} = 0b00; // 32-bit size flag5801 }5802 5803 def Drr : BaseTwoOperandFPData<opcode, FPR64, asm,5804 [(set (f64 FPR64:$Rd),5805 (node (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]> {5806 let Inst{23-22} = 0b01; // 64-bit size flag5807 }5808}5809 5810multiclass TwoOperandFPDataNeg<bits<4> opcode, string asm,5811 SDPatternOperator node> {5812 def Hrr : BaseTwoOperandFPData<opcode, FPR16, asm,5813 [(set (f16 FPR16:$Rd), (fneg (node (f16 FPR16:$Rn), (f16 FPR16:$Rm))))]> {5814 let Inst{23-22} = 0b11; // 16-bit size flag5815 let Predicates = [HasFullFP16];5816 }5817 5818 def Srr : BaseTwoOperandFPData<opcode, FPR32, asm,5819 [(set FPR32:$Rd, (fneg (node FPR32:$Rn, (f32 FPR32:$Rm))))]> {5820 let Inst{23-22} = 0b00; // 32-bit size flag5821 }5822 5823 def Drr : BaseTwoOperandFPData<opcode, FPR64, asm,5824 [(set FPR64:$Rd, (fneg (node FPR64:$Rn, (f64 FPR64:$Rm))))]> {5825 let Inst{23-22} = 0b01; // 64-bit size flag5826 }5827}5828 5829 5830//---5831// Three operand floating point data processing5832//---5833 5834let mayRaiseFPException = 1, Uses = [FPCR] in5835class BaseThreeOperandFPData<bit isNegated, bit isSub,5836 RegisterClass regtype, string asm, list<dag> pat>5837 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, regtype: $Ra),5838 asm, "\t$Rd, $Rn, $Rm, $Ra", "", pat>,5839 Sched<[WriteFMul]> {5840 bits<5> Rd;5841 bits<5> Rn;5842 bits<5> Rm;5843 bits<5> Ra;5844 let Inst{31-24} = 0b00011111;5845 let Inst{21} = isNegated;5846 let Inst{20-16} = Rm;5847 let Inst{15} = isSub;5848 let Inst{14-10} = Ra;5849 let Inst{9-5} = Rn;5850 let Inst{4-0} = Rd;5851}5852 5853multiclass ThreeOperandFPData<bit isNegated, bit isSub,string asm,5854 SDPatternOperator node> {5855 def Hrrr : BaseThreeOperandFPData<isNegated, isSub, FPR16, asm,5856 [(set (f16 FPR16:$Rd),5857 (node (f16 FPR16:$Rn), (f16 FPR16:$Rm), (f16 FPR16:$Ra)))]> {5858 let Inst{23-22} = 0b11; // 16-bit size flag5859 let Predicates = [HasFullFP16];5860 }5861 5862 def Srrr : BaseThreeOperandFPData<isNegated, isSub, FPR32, asm,5863 [(set FPR32:$Rd,5864 (node (f32 FPR32:$Rn), (f32 FPR32:$Rm), (f32 FPR32:$Ra)))]> {5865 let Inst{23-22} = 0b00; // 32-bit size flag5866 }5867 5868 def Drrr : BaseThreeOperandFPData<isNegated, isSub, FPR64, asm,5869 [(set FPR64:$Rd,5870 (node (f64 FPR64:$Rn), (f64 FPR64:$Rm), (f64 FPR64:$Ra)))]> {5871 let Inst{23-22} = 0b01; // 64-bit size flag5872 }5873 5874 let Predicates = [HasFullFP16] in {5875 def : Pat<(f16 (node (f16 FPR16:$Rn),5876 (f16 (extractelt (v8f16 V128:$Rm), (i64 0))),5877 (f16 FPR16:$Ra))),5878 (!cast<Instruction>(NAME # Hrrr)5879 FPR16:$Rn, (f16 (EXTRACT_SUBREG V128:$Rm, hsub)), FPR16:$Ra)>;5880 5881 def : Pat<(f16 (node (f16 (extractelt (v8f16 V128:$Rn), (i64 0))),5882 (f16 FPR16:$Rm),5883 (f16 FPR16:$Ra))),5884 (!cast<Instruction>(NAME # Hrrr)5885 (f16 (EXTRACT_SUBREG V128:$Rn, hsub)), FPR16:$Rm, FPR16:$Ra)>;5886 5887 def : Pat<(f16 (node (f16 (extractelt (v8f16 V128:$Rn), (i64 0))),5888 (f16 (extractelt (v8f16 V128:$Rm), (i64 0))),5889 (f16 FPR16:$Ra))),5890 (!cast<Instruction>(NAME # Hrrr)5891 (f16 (EXTRACT_SUBREG V128:$Rn, hsub)),5892 (f16 (EXTRACT_SUBREG V128:$Rm, hsub)), FPR16:$Ra)>;5893 }5894 5895 def : Pat<(f32 (node (f32 FPR32:$Rn),5896 (f32 (extractelt (v4f32 V128:$Rm), (i64 0))),5897 (f32 FPR32:$Ra))),5898 (!cast<Instruction>(NAME # Srrr)5899 FPR32:$Rn, (EXTRACT_SUBREG V128:$Rm, ssub), FPR32:$Ra)>;5900 5901 def : Pat<(f32 (node (f32 (extractelt (v4f32 V128:$Rn), (i64 0))),5902 (f32 FPR32:$Rm),5903 (f32 FPR32:$Ra))),5904 (!cast<Instruction>(NAME # Srrr)5905 (EXTRACT_SUBREG V128:$Rn, ssub), FPR32:$Rm, FPR32:$Ra)>;5906 5907 def : Pat<(f32 (node (f32 (extractelt (v4f32 V128:$Rn), (i64 0))),5908 (f32 (extractelt (v4f32 V128:$Rm), (i64 0))),5909 (f32 FPR32:$Ra))),5910 (!cast<Instruction>(NAME # Srrr)5911 (EXTRACT_SUBREG V128:$Rn, ssub),5912 (EXTRACT_SUBREG V128:$Rm, ssub), FPR32:$Ra)>;5913 5914 def : Pat<(f64 (node (f64 FPR64:$Rn),5915 (f64 (extractelt (v2f64 V128:$Rm), (i64 0))),5916 (f64 FPR64:$Ra))),5917 (!cast<Instruction>(NAME # Drrr)5918 FPR64:$Rn, (EXTRACT_SUBREG V128:$Rm, dsub), FPR64:$Ra)>;5919 5920 def : Pat<(f64 (node (f64 (extractelt (v2f64 V128:$Rn), (i64 0))),5921 (f64 FPR64:$Rm),5922 (f64 FPR64:$Ra))),5923 (!cast<Instruction>(NAME # Drrr)5924 (EXTRACT_SUBREG V128:$Rn, dsub), FPR64:$Rm, FPR64:$Ra)>;5925 5926 def : Pat<(f64 (node (f64 (extractelt (v2f64 V128:$Rn), (i64 0))),5927 (f64 (extractelt (v2f64 V128:$Rm), (i64 0))),5928 (f64 FPR64:$Ra))),5929 (!cast<Instruction>(NAME # Drrr)5930 (EXTRACT_SUBREG V128:$Rn, dsub),5931 (EXTRACT_SUBREG V128:$Rm, dsub), FPR64:$Ra)>;5932}5933 5934//---5935// Floating point data comparisons5936//---5937 5938let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in5939class BaseOneOperandFPComparison<bit signalAllNans,5940 RegisterClass regtype, string asm,5941 list<dag> pat>5942 : I<(outs), (ins regtype:$Rn), asm, "\t$Rn, #0.0", "", pat>,5943 Sched<[WriteFCmp]> {5944 bits<5> Rn;5945 let Inst{31-24} = 0b00011110;5946 let Inst{21} = 1;5947 5948 let Inst{15-10} = 0b001000;5949 let Inst{9-5} = Rn;5950 let Inst{4} = signalAllNans;5951 let Inst{3-0} = 0b1000;5952 5953 // Rm should be 0b00000 canonically, but we need to accept any value.5954 let PostEncoderMethod = "fixOneOperandFPComparison";5955}5956 5957let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in5958class BaseTwoOperandFPComparison<bit signalAllNans, RegisterClass regtype,5959 string asm, list<dag> pat>5960 : I<(outs), (ins regtype:$Rn, regtype:$Rm), asm, "\t$Rn, $Rm", "", pat>,5961 Sched<[WriteFCmp]> {5962 bits<5> Rm;5963 bits<5> Rn;5964 let Inst{31-24} = 0b00011110;5965 let Inst{21} = 1;5966 let Inst{20-16} = Rm;5967 let Inst{15-10} = 0b001000;5968 let Inst{9-5} = Rn;5969 let Inst{4} = signalAllNans;5970 let Inst{3-0} = 0b0000;5971}5972 5973multiclass FPComparison<bit signalAllNans, string asm,5974 SDPatternOperator OpNode = null_frag> {5975 let Defs = [NZCV] in {5976 def Hrr : BaseTwoOperandFPComparison<signalAllNans, FPR16, asm,5977 [(set NZCV, (OpNode (f16 FPR16:$Rn), (f16 FPR16:$Rm)))]> {5978 let Inst{23-22} = 0b11;5979 let Predicates = [HasFullFP16];5980 }5981 5982 def Hri : BaseOneOperandFPComparison<signalAllNans, FPR16, asm,5983 [(set NZCV, (OpNode (f16 FPR16:$Rn), fpimm0))]> {5984 let Inst{23-22} = 0b11;5985 let Predicates = [HasFullFP16];5986 }5987 5988 def Srr : BaseTwoOperandFPComparison<signalAllNans, FPR32, asm,5989 [(set NZCV, (OpNode FPR32:$Rn, (f32 FPR32:$Rm)))]> {5990 let Inst{23-22} = 0b00;5991 }5992 5993 def Sri : BaseOneOperandFPComparison<signalAllNans, FPR32, asm,5994 [(set NZCV, (OpNode (f32 FPR32:$Rn), fpimm0))]> {5995 let Inst{23-22} = 0b00;5996 }5997 5998 def Drr : BaseTwoOperandFPComparison<signalAllNans, FPR64, asm,5999 [(set NZCV, (OpNode FPR64:$Rn, (f64 FPR64:$Rm)))]> {6000 let Inst{23-22} = 0b01;6001 }6002 6003 def Dri : BaseOneOperandFPComparison<signalAllNans, FPR64, asm,6004 [(set NZCV, (OpNode (f64 FPR64:$Rn), fpimm0))]> {6005 let Inst{23-22} = 0b01;6006 }6007 } // Defs = [NZCV]6008}6009 6010//---6011// Floating point conditional comparisons6012//---6013 6014let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in6015class BaseFPCondComparison<bit signalAllNans, RegisterClass regtype,6016 string mnemonic, list<dag> pat>6017 : I<(outs), (ins regtype:$Rn, regtype:$Rm, imm32_0_15:$nzcv, ccode:$cond),6018 mnemonic, "\t$Rn, $Rm, $nzcv, $cond", "", pat>,6019 Sched<[WriteFCmp]> {6020 let Uses = [NZCV];6021 let Defs = [NZCV];6022 6023 bits<5> Rn;6024 bits<5> Rm;6025 bits<4> nzcv;6026 bits<4> cond;6027 6028 let Inst{31-24} = 0b00011110;6029 let Inst{21} = 1;6030 let Inst{20-16} = Rm;6031 let Inst{15-12} = cond;6032 let Inst{11-10} = 0b01;6033 let Inst{9-5} = Rn;6034 let Inst{4} = signalAllNans;6035 let Inst{3-0} = nzcv;6036}6037 6038multiclass FPCondComparison<bit signalAllNans, string mnemonic,6039 SDPatternOperator OpNode = null_frag> {6040 def Hrr : BaseFPCondComparison<signalAllNans, FPR16, mnemonic,6041 [(set NZCV, (OpNode (f16 FPR16:$Rn), (f16 FPR16:$Rm), (i32 imm:$nzcv),6042 (i32 imm:$cond), NZCV))]> {6043 let Inst{23-22} = 0b11;6044 let Predicates = [HasFullFP16];6045 }6046 6047 def Srr : BaseFPCondComparison<signalAllNans, FPR32, mnemonic,6048 [(set NZCV, (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm), (i32 imm:$nzcv),6049 (i32 imm:$cond), NZCV))]> {6050 let Inst{23-22} = 0b00;6051 }6052 6053 def Drr : BaseFPCondComparison<signalAllNans, FPR64, mnemonic,6054 [(set NZCV, (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm), (i32 imm:$nzcv),6055 (i32 imm:$cond), NZCV))]> {6056 let Inst{23-22} = 0b01;6057 }6058}6059 6060//---6061// Floating point conditional select6062//---6063 6064class BaseFPCondSelect<RegisterClass regtype, ValueType vt, string asm>6065 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, ccode:$cond),6066 asm, "\t$Rd, $Rn, $Rm, $cond", "",6067 [(set regtype:$Rd,6068 (AArch64csel (vt regtype:$Rn), regtype:$Rm,6069 (i32 imm:$cond), NZCV))]>,6070 Sched<[WriteF]> {6071 bits<5> Rd;6072 bits<5> Rn;6073 bits<5> Rm;6074 bits<4> cond;6075 6076 let Inst{31-24} = 0b00011110;6077 let Inst{21} = 1;6078 let Inst{20-16} = Rm;6079 let Inst{15-12} = cond;6080 let Inst{11-10} = 0b11;6081 let Inst{9-5} = Rn;6082 let Inst{4-0} = Rd;6083}6084 6085multiclass FPCondSelect<string asm> {6086 let Uses = [NZCV] in {6087 def Hrrr : BaseFPCondSelect<FPR16, f16, asm> {6088 let Inst{23-22} = 0b11;6089 let Predicates = [HasFullFP16];6090 }6091 6092 def Srrr : BaseFPCondSelect<FPR32, f32, asm> {6093 let Inst{23-22} = 0b00;6094 }6095 6096 def Drrr : BaseFPCondSelect<FPR64, f64, asm> {6097 let Inst{23-22} = 0b01;6098 }6099 } // Uses = [NZCV]6100}6101 6102//---6103// Floating move immediate6104//---6105 6106class BaseFPMoveImmediate<RegisterClass regtype, Operand fpimmtype, string asm>6107 : I<(outs regtype:$Rd), (ins fpimmtype:$imm), asm, "\t$Rd, $imm", "",6108 [(set regtype:$Rd, fpimmtype:$imm)]>,6109 Sched<[WriteFImm]> {6110 bits<5> Rd;6111 bits<8> imm;6112 let Inst{31-24} = 0b00011110;6113 let Inst{21} = 1;6114 let Inst{20-13} = imm;6115 let Inst{12-5} = 0b10000000;6116 let Inst{4-0} = Rd;6117}6118 6119multiclass FPMoveImmediate<string asm> {6120 def Hi : BaseFPMoveImmediate<FPR16, fpimm16, asm> {6121 let Inst{23-22} = 0b11;6122 let Predicates = [HasFullFP16];6123 }6124 6125 def Si : BaseFPMoveImmediate<FPR32, fpimm32, asm> {6126 let Inst{23-22} = 0b00;6127 }6128 6129 def Di : BaseFPMoveImmediate<FPR64, fpimm64, asm> {6130 let Inst{23-22} = 0b01;6131 }6132}6133} // end of 'let Predicates = [HasFPARMv8]'6134 6135//----------------------------------------------------------------------------6136// AdvSIMD6137//----------------------------------------------------------------------------6138 6139let Predicates = [HasNEON] in {6140 6141//----------------------------------------------------------------------------6142// AdvSIMD three register vector instructions6143//----------------------------------------------------------------------------6144 6145let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in6146class BaseSIMDThreeSameVector<bit Q, bit U, bits<3> size, bits<5> opcode,6147 RegisterOperand regtype, string asm, string kind,6148 list<dag> pattern>6149 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm,6150 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind #6151 "|" # kind # "\t$Rd, $Rn, $Rm|}", "", pattern>,6152 Sched<[!if(Q, WriteVq, WriteVd)]> {6153 bits<5> Rd;6154 bits<5> Rn;6155 bits<5> Rm;6156 let Inst{31} = 0;6157 let Inst{30} = Q;6158 let Inst{29} = U;6159 let Inst{28-24} = 0b01110;6160 let Inst{23-21} = size;6161 let Inst{20-16} = Rm;6162 let Inst{15-11} = opcode;6163 let Inst{10} = 1;6164 let Inst{9-5} = Rn;6165 let Inst{4-0} = Rd;6166}6167 6168let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in6169class BaseSIMDThreeSameVectorTied<bit Q, bit U, bits<3> size, bits<5> opcode,6170 RegisterOperand regtype, string asm, string kind,6171 list<dag> pattern>6172 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn, regtype:$Rm), asm,6173 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind #6174 "|" # kind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>,6175 Sched<[!if(Q, WriteVq, WriteVd)]> {6176 bits<5> Rd;6177 bits<5> Rn;6178 bits<5> Rm;6179 let Inst{31} = 0;6180 let Inst{30} = Q;6181 let Inst{29} = U;6182 let Inst{28-24} = 0b01110;6183 let Inst{23-21} = size;6184 let Inst{20-16} = Rm;6185 let Inst{15-11} = opcode;6186 let Inst{10} = 1;6187 let Inst{9-5} = Rn;6188 let Inst{4-0} = Rd;6189}6190 6191let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in6192class BaseSIMDThreeSameVectorPseudo<RegisterOperand regtype, list<dag> pattern>6193 : Pseudo<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn, regtype:$Rm), pattern>,6194 Sched<[!if(!eq(regtype, V128), WriteVq, WriteVd)]>;6195 6196multiclass SIMDLogicalThreeVectorPseudo<SDPatternOperator OpNode> {6197 def v8i8 : BaseSIMDThreeSameVectorPseudo<V64,6198 [(set (v8i8 V64:$dst),6199 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;6200 def v16i8 : BaseSIMDThreeSameVectorPseudo<V128,6201 [(set (v16i8 V128:$dst),6202 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),6203 (v16i8 V128:$Rm)))]>;6204 6205 def : Pat<(v4i16 (OpNode (v4i16 V64:$LHS), (v4i16 V64:$MHS),6206 (v4i16 V64:$RHS))),6207 (!cast<Instruction>(NAME#"v8i8")6208 V64:$LHS, V64:$MHS, V64:$RHS)>;6209 def : Pat<(v2i32 (OpNode (v2i32 V64:$LHS), (v2i32 V64:$MHS),6210 (v2i32 V64:$RHS))),6211 (!cast<Instruction>(NAME#"v8i8")6212 V64:$LHS, V64:$MHS, V64:$RHS)>;6213 def : Pat<(v1i64 (OpNode (v1i64 V64:$LHS), (v1i64 V64:$MHS),6214 (v1i64 V64:$RHS))),6215 (!cast<Instruction>(NAME#"v8i8")6216 V64:$LHS, V64:$MHS, V64:$RHS)>;6217 6218 def : Pat<(v8i16 (OpNode (v8i16 V128:$LHS), (v8i16 V128:$MHS),6219 (v8i16 V128:$RHS))),6220 (!cast<Instruction>(NAME#"v16i8")6221 V128:$LHS, V128:$MHS, V128:$RHS)>;6222 def : Pat<(v4i32 (OpNode (v4i32 V128:$LHS), (v4i32 V128:$MHS),6223 (v4i32 V128:$RHS))),6224 (!cast<Instruction>(NAME#"v16i8")6225 V128:$LHS, V128:$MHS, V128:$RHS)>;6226 def : Pat<(v2i64 (OpNode (v2i64 V128:$LHS), (v2i64 V128:$MHS),6227 (v2i64 V128:$RHS))),6228 (!cast<Instruction>(NAME#"v16i8")6229 V128:$LHS, V128:$MHS, V128:$RHS)>;6230}6231 6232// All operand sizes distinguished in the encoding.6233multiclass SIMDThreeSameVector<bit U, bits<5> opc, string asm,6234 SDPatternOperator OpNode> {6235 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64,6236 asm, ".8b",6237 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;6238 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128,6239 asm, ".16b",6240 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>;6241 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64,6242 asm, ".4h",6243 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;6244 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128,6245 asm, ".8h",6246 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;6247 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64,6248 asm, ".2s",6249 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;6250 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128,6251 asm, ".4s",6252 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;6253 def v2i64 : BaseSIMDThreeSameVector<1, U, 0b111, opc, V128,6254 asm, ".2d",6255 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>;6256}6257 6258// As above, but D sized elements unsupported.6259multiclass SIMDThreeSameVectorBHS<bit U, bits<5> opc, string asm,6260 SDPatternOperator OpNode> {6261 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64,6262 asm, ".8b",6263 [(set V64:$Rd, (v8i8 (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm))))]>;6264 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128,6265 asm, ".16b",6266 [(set V128:$Rd, (v16i8 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm))))]>;6267 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64,6268 asm, ".4h",6269 [(set V64:$Rd, (v4i16 (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm))))]>;6270 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128,6271 asm, ".8h",6272 [(set V128:$Rd, (v8i16 (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm))))]>;6273 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64,6274 asm, ".2s",6275 [(set V64:$Rd, (v2i32 (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm))))]>;6276 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128,6277 asm, ".4s",6278 [(set V128:$Rd, (v4i32 (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm))))]>;6279}6280 6281multiclass SIMDThreeSameVectorBHSTied<bit U, bits<5> opc, string asm,6282 SDPatternOperator OpNode> {6283 def v8i8 : BaseSIMDThreeSameVectorTied<0, U, 0b001, opc, V64,6284 asm, ".8b",6285 [(set (v8i8 V64:$dst),6286 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;6287 def v16i8 : BaseSIMDThreeSameVectorTied<1, U, 0b001, opc, V128,6288 asm, ".16b",6289 [(set (v16i8 V128:$dst),6290 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>;6291 def v4i16 : BaseSIMDThreeSameVectorTied<0, U, 0b011, opc, V64,6292 asm, ".4h",6293 [(set (v4i16 V64:$dst),6294 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;6295 def v8i16 : BaseSIMDThreeSameVectorTied<1, U, 0b011, opc, V128,6296 asm, ".8h",6297 [(set (v8i16 V128:$dst),6298 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;6299 def v2i32 : BaseSIMDThreeSameVectorTied<0, U, 0b101, opc, V64,6300 asm, ".2s",6301 [(set (v2i32 V64:$dst),6302 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;6303 def v4i32 : BaseSIMDThreeSameVectorTied<1, U, 0b101, opc, V128,6304 asm, ".4s",6305 [(set (v4i32 V128:$dst),6306 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;6307}6308 6309// As above, but only B sized elements supported.6310multiclass SIMDThreeSameVectorB<bit U, bits<5> opc, string asm,6311 SDPatternOperator OpNode> {6312 def v8i8 : BaseSIMDThreeSameVector<0, U, 0b001, opc, V64,6313 asm, ".8b",6314 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;6315 def v16i8 : BaseSIMDThreeSameVector<1, U, 0b001, opc, V128,6316 asm, ".16b",6317 [(set (v16i8 V128:$Rd),6318 (OpNode (v16i8 V128:$Rn), (v16i8 V128:$Rm)))]>;6319}6320 6321// As above, but only floating point elements supported.6322let mayRaiseFPException = 1, Uses = [FPCR] in6323multiclass SIMDThreeSameVectorFP<bit U, bit S, bits<3> opc,6324 string asm, SDPatternOperator OpNode> {6325 let Predicates = [HasNEON, HasFullFP16] in {6326 def v4f16 : BaseSIMDThreeSameVector<0, U, {S,0b10}, {0b00,opc}, V64,6327 asm, ".4h",6328 [(set (v4f16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>;6329 def v8f16 : BaseSIMDThreeSameVector<1, U, {S,0b10}, {0b00,opc}, V128,6330 asm, ".8h",6331 [(set (v8f16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>;6332 } // Predicates = [HasNEON, HasFullFP16]6333 def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0b01}, {0b11,opc}, V64,6334 asm, ".2s",6335 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>;6336 def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0b01}, {0b11,opc}, V128,6337 asm, ".4s",6338 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>;6339 def v2f64 : BaseSIMDThreeSameVector<1, U, {S,0b11}, {0b11,opc}, V128,6340 asm, ".2d",6341 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>;6342}6343 6344let mayRaiseFPException = 1, Uses = [FPCR] in6345multiclass SIMDThreeSameVectorFPCmp<bit U, bit S, bits<3> opc,6346 string asm,6347 SDPatternOperator OpNode> {6348 let Predicates = [HasNEON, HasFullFP16] in {6349 def v4f16 : BaseSIMDThreeSameVector<0, U, {S,0b10}, {0b00,opc}, V64,6350 asm, ".4h",6351 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>;6352 def v8f16 : BaseSIMDThreeSameVector<1, U, {S,0b10}, {0b00,opc}, V128,6353 asm, ".8h",6354 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>;6355 } // Predicates = [HasNEON, HasFullFP16]6356 def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0b01}, {0b11,opc}, V64,6357 asm, ".2s",6358 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>;6359 def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0b01}, {0b11,opc}, V128,6360 asm, ".4s",6361 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>;6362 def v2f64 : BaseSIMDThreeSameVector<1, U, {S,0b11}, {0b11,opc}, V128,6363 asm, ".2d",6364 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>;6365}6366 6367let mayRaiseFPException = 1, Uses = [FPCR] in6368multiclass SIMDThreeSameVectorFPTied<bit U, bit S, bits<3> opc,6369 string asm, SDPatternOperator OpNode> {6370 let Predicates = [HasNEON, HasFullFP16] in {6371 def v4f16 : BaseSIMDThreeSameVectorTied<0, U, {S,0b10}, {0b00,opc}, V64,6372 asm, ".4h",6373 [(set (v4f16 V64:$dst),6374 (OpNode (v4f16 V64:$Rd), (v4f16 V64:$Rn), (v4f16 V64:$Rm)))]>;6375 def v8f16 : BaseSIMDThreeSameVectorTied<1, U, {S,0b10}, {0b00,opc}, V128,6376 asm, ".8h",6377 [(set (v8f16 V128:$dst),6378 (OpNode (v8f16 V128:$Rd), (v8f16 V128:$Rn), (v8f16 V128:$Rm)))]>;6379 } // Predicates = [HasNEON, HasFullFP16]6380 def v2f32 : BaseSIMDThreeSameVectorTied<0, U, {S,0b01}, {0b11,opc}, V64,6381 asm, ".2s",6382 [(set (v2f32 V64:$dst),6383 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn), (v2f32 V64:$Rm)))]>;6384 def v4f32 : BaseSIMDThreeSameVectorTied<1, U, {S,0b01}, {0b11,opc}, V128,6385 asm, ".4s",6386 [(set (v4f32 V128:$dst),6387 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn), (v4f32 V128:$Rm)))]>;6388 def v2f64 : BaseSIMDThreeSameVectorTied<1, U, {S,0b11}, {0b11,opc}, V128,6389 asm, ".2d",6390 [(set (v2f64 V128:$dst),6391 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn), (v2f64 V128:$Rm)))]>;6392}6393 6394// As above, but D and B sized elements unsupported.6395let mayRaiseFPException = 1, Uses = [FPCR] in6396multiclass SIMDThreeSameVectorHS<bit U, bits<5> opc, string asm,6397 SDPatternOperator OpNode> {6398 def v4i16 : BaseSIMDThreeSameVector<0, U, 0b011, opc, V64,6399 asm, ".4h",6400 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;6401 def v8i16 : BaseSIMDThreeSameVector<1, U, 0b011, opc, V128,6402 asm, ".8h",6403 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;6404 def v2i32 : BaseSIMDThreeSameVector<0, U, 0b101, opc, V64,6405 asm, ".2s",6406 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;6407 def v4i32 : BaseSIMDThreeSameVector<1, U, 0b101, opc, V128,6408 asm, ".4s",6409 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;6410}6411 6412// Logical three vector ops share opcode bits, and only use B sized elements.6413multiclass SIMDLogicalThreeVector<bit U, bits<2> size, string asm,6414 SDPatternOperator OpNode = null_frag> {6415 def v8i8 : BaseSIMDThreeSameVector<0, U, {size,1}, 0b00011, V64,6416 asm, ".8b",6417 [(set (v8i8 V64:$Rd), (OpNode V64:$Rn, V64:$Rm))]>;6418 def v16i8 : BaseSIMDThreeSameVector<1, U, {size,1}, 0b00011, V128,6419 asm, ".16b",6420 [(set (v16i8 V128:$Rd), (OpNode V128:$Rn, V128:$Rm))]>;6421 6422 def : Pat<(v4i16 (OpNode V64:$LHS, V64:$RHS)),6423 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>;6424 def : Pat<(v2i32 (OpNode V64:$LHS, V64:$RHS)),6425 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>;6426 def : Pat<(v1i64 (OpNode V64:$LHS, V64:$RHS)),6427 (!cast<Instruction>(NAME#"v8i8") V64:$LHS, V64:$RHS)>;6428 6429 def : Pat<(v8i16 (OpNode V128:$LHS, V128:$RHS)),6430 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>;6431 def : Pat<(v4i32 (OpNode V128:$LHS, V128:$RHS)),6432 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>;6433 def : Pat<(v2i64 (OpNode V128:$LHS, V128:$RHS)),6434 (!cast<Instruction>(NAME#"v16i8") V128:$LHS, V128:$RHS)>;6435}6436 6437multiclass SIMDLogicalThreeVectorTied<bit U, bits<2> size,6438 string asm, SDPatternOperator OpNode = null_frag> {6439 def v8i8 : BaseSIMDThreeSameVectorTied<0, U, {size,1}, 0b00011, V64,6440 asm, ".8b",6441 [(set (v8i8 V64:$dst),6442 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;6443 def v16i8 : BaseSIMDThreeSameVectorTied<1, U, {size,1}, 0b00011, V128,6444 asm, ".16b",6445 [(set (v16i8 V128:$dst),6446 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),6447 (v16i8 V128:$Rm)))]>;6448 6449 def : Pat<(v4i16 (OpNode (v4i16 V64:$LHS), (v4i16 V64:$MHS),6450 (v4i16 V64:$RHS))),6451 (!cast<Instruction>(NAME#"v8i8")6452 V64:$LHS, V64:$MHS, V64:$RHS)>;6453 def : Pat<(v2i32 (OpNode (v2i32 V64:$LHS), (v2i32 V64:$MHS),6454 (v2i32 V64:$RHS))),6455 (!cast<Instruction>(NAME#"v8i8")6456 V64:$LHS, V64:$MHS, V64:$RHS)>;6457 def : Pat<(v1i64 (OpNode (v1i64 V64:$LHS), (v1i64 V64:$MHS),6458 (v1i64 V64:$RHS))),6459 (!cast<Instruction>(NAME#"v8i8")6460 V64:$LHS, V64:$MHS, V64:$RHS)>;6461 6462 def : Pat<(v8i16 (OpNode (v8i16 V128:$LHS), (v8i16 V128:$MHS),6463 (v8i16 V128:$RHS))),6464 (!cast<Instruction>(NAME#"v16i8")6465 V128:$LHS, V128:$MHS, V128:$RHS)>;6466 def : Pat<(v4i32 (OpNode (v4i32 V128:$LHS), (v4i32 V128:$MHS),6467 (v4i32 V128:$RHS))),6468 (!cast<Instruction>(NAME#"v16i8")6469 V128:$LHS, V128:$MHS, V128:$RHS)>;6470 def : Pat<(v2i64 (OpNode (v2i64 V128:$LHS), (v2i64 V128:$MHS),6471 (v2i64 V128:$RHS))),6472 (!cast<Instruction>(NAME#"v16i8")6473 V128:$LHS, V128:$MHS, V128:$RHS)>;6474}6475 6476// ARMv8.2-A Dot Product Instructions (Vector): These instructions extract6477// bytes from S-sized elements.6478class BaseSIMDThreeSameVectorDot<bit Q, bit U, bits<2> sz, bits<4> opc, string asm,6479 string kind1, string kind2, RegisterOperand RegType,6480 ValueType AccumType, ValueType InputType,6481 SDPatternOperator OpNode> :6482 BaseSIMDThreeSameVectorTied<Q, U, {sz, 0b0}, {0b1, opc}, RegType, asm, kind1,6483 [(set (AccumType RegType:$dst),6484 (OpNode (AccumType RegType:$Rd),6485 (InputType RegType:$Rn),6486 (InputType RegType:$Rm)))]> {6487 6488 let AsmString = !strconcat(asm, "{\t$Rd" # kind1 # ", $Rn" # kind2 # ", $Rm" # kind2 #6489 "|" # kind1 # "\t$Rd, $Rn, $Rm}");6490}6491 6492multiclass SIMDThreeSameVectorDot<bit U, bit Mixed, string asm, SDPatternOperator OpNode> {6493 def v8i8 : BaseSIMDThreeSameVectorDot<0, U, 0b10, {0b001, Mixed}, asm, ".2s", ".8b", V64,6494 v2i32, v8i8, OpNode>;6495 def v16i8 : BaseSIMDThreeSameVectorDot<1, U, 0b10, {0b001, Mixed}, asm, ".4s", ".16b", V128,6496 v4i32, v16i8, OpNode>;6497}6498 6499// ARMv8.2-A Fused Multiply Add-Long Instructions (Vector): These instructions6500// select inputs from 4H vectors and accumulate outputs to a 2S vector (or from6501// 8H to 4S, when Q=1).6502let mayRaiseFPException = 1, Uses = [FPCR] in6503class BaseSIMDThreeSameVectorFML<bit Q, bit U, bit b13, bits<3> size, string asm, string kind1,6504 string kind2, RegisterOperand RegType,6505 ValueType AccumType, ValueType InputType,6506 SDPatternOperator OpNode> :6507 BaseSIMDThreeSameVectorTied<Q, U, size, 0b11101, RegType, asm, kind1,6508 [(set (AccumType RegType:$dst),6509 (OpNode (AccumType RegType:$Rd),6510 (InputType RegType:$Rn),6511 (InputType RegType:$Rm)))]> {6512 let AsmString = !strconcat(asm, "{\t$Rd" # kind1 # ", $Rn" # kind2 # ", $Rm" # kind2 # 6513 "|" # kind1 # "\t$Rd, $Rn, $Rm}");6514 let Inst{13} = b13;6515}6516 6517multiclass SIMDThreeSameVectorFML<bit U, bit b13, bits<3> size, string asm,6518 SDPatternOperator OpNode> {6519 def v4f16 : BaseSIMDThreeSameVectorFML<0, U, b13, size, asm, ".2s", ".2h", V64,6520 v2f32, v4f16, OpNode>;6521 def v8f16 : BaseSIMDThreeSameVectorFML<1, U, b13, size, asm, ".4s", ".4h", V128,6522 v4f32, v8f16, OpNode>;6523}6524 6525multiclass SIMDThreeSameVectorMLA<bit Q, string asm, SDPatternOperator op> {6526 def v16i8_v8f16 : BaseSIMDThreeSameVectorDot<Q, 0b0, 0b11, 0b1111, asm, ".8h", ".16b",6527 V128, v8f16, v16i8, op>;6528}6529 6530multiclass SIMDThreeSameVectorMLAL<bit Q, bits<2> sz, string asm, SDPatternOperator op> {6531 def v4f32 : BaseSIMDThreeSameVectorDot<Q, 0b0, sz, 0b1000, asm, ".4s", ".16b",6532 V128, v4f32, v16i8, op>;6533}6534 6535multiclass SIMDThreeSameVectorFMLA<string asm> {6536 def v8f16_v8f16 : BaseSIMDThreeSameVectorDot<0b1, 0b0, 0b11, 0b1101, asm, ".8h", ".8h",6537 V128, v8f16, v8f16, null_frag>;6538}6539 6540multiclass SIMDThreeSameVectorFMLAWiden<string asm> {6541 def v8f16_v4f32 : BaseSIMDThreeSameVectorDot<0b1, 0b0, 0b01, 0b1101, asm, ".4s", ".8h",6542 V128, v4f32, v8f16, null_frag>;6543}6544 6545multiclass SIMDThreeSameVectorFDot<string asm, SDPatternOperator OpNode = null_frag> {6546 def v4f16_v2f32 : BaseSIMDThreeSameVectorDot<0, 0, 0b10, 0b1111, asm, ".2s", ".4h", V64,6547 v2f32, v4f16, OpNode>;6548 def v8f16_v4f32 : BaseSIMDThreeSameVectorDot<1, 0, 0b10, 0b1111, asm, ".4s", ".8h", V128,6549 v4f32, v8f16, OpNode>;6550}6551 6552// FP8 assembly/disassembly classes6553 6554//----------------------------------------------------------------------------6555// FP8 Advanced SIMD three-register extension6556//----------------------------------------------------------------------------6557class BaseSIMDThreeVectors<bit Q, bit U, bits<2> size, bits<4> op,6558 RegisterOperand regtype1,6559 RegisterOperand regtype2, string asm,6560 string kind1, string kind2>6561 : I<(outs regtype1:$Rd), (ins regtype2:$Rn, regtype2:$Rm), asm,6562 "\t$Rd" # kind1 # ", $Rn" # kind2 # ", $Rm" # kind2, "", []>, Sched<[]> {6563 bits<5> Rd;6564 bits<5> Rn;6565 bits<5> Rm;6566 let Inst{31} = 0;6567 let Inst{30} = Q;6568 let Inst{29} = U;6569 let Inst{28-24} = 0b01110;6570 let Inst{23-22} = size;6571 let Inst{21} = 0b0;6572 let Inst{20-16} = Rm;6573 let Inst{15} = 0b1;6574 let Inst{14-11} = op;6575 let Inst{10} = 0b1;6576 let Inst{9-5} = Rn;6577 let Inst{4-0} = Rd;6578}6579 6580 6581// FCVTN (FP16 to FP8)6582multiclass SIMD_FP8_CVTN_F16<string asm, SDPatternOperator Op> {6583 let Uses = [FPMR, FPCR], mayLoad = 1 in {6584 def v8f8 : BaseSIMDThreeVectors<0b0, 0b0, 0b01, 0b1110, V64, V64, asm, ".8b",".4h">;6585 def v16f8 : BaseSIMDThreeVectors<0b1, 0b0, 0b01, 0b1110, V128, V128, asm, ".16b", ".8h">;6586 }6587 def : Pat<(v8i8 (Op (v4f16 V64:$Rn), (v4f16 V64:$Rm))),6588 (!cast<Instruction>(NAME # v8f8) V64:$Rn, V64:$Rm)>;6589 def : Pat<(v16i8 (Op (v8f16 V128:$Rn), (v8f16 V128:$Rm))),6590 (!cast<Instruction>(NAME # v16f8) V128:$Rn, V128:$Rm)>;6591}6592 6593// FCVTN, FCVTN2 (FP32 to FP8)6594multiclass SIMD_FP8_CVTN_F32<string asm, SDPatternOperator Op> {6595 let Uses = [FPMR, FPCR], mayLoad = 1 in {6596 def v8f8 : BaseSIMDThreeVectors<0b0, 0b0, 0b00, 0b1110, V64, V128, asm, ".8b", ".4s">;6597 def 2v16f8 : BaseSIMDThreeSameVectorDot<0b1, 0b0, 0b00, 0b1110, asm#2, ".16b", ".4s",6598 V128, v16i8, v4f32, null_frag>;6599 }6600 6601 def : Pat<(v8i8 (Op (v4f32 V128:$Rn), (v4f32 V128:$Rm))),6602 (!cast<Instruction>(NAME # v8f8) V128:$Rn, V128:$Rm)>;6603 6604 def : Pat<(v16i8 (!cast<SDPatternOperator>(Op # 2) (v16i8 V128:$_Rd), (v4f32 V128:$Rn), (v4f32 V128:$Rm))),6605 (!cast<Instruction>(NAME # 2v16f8) V128:$_Rd, V128:$Rn, V128:$Rm)>;6606}6607 6608multiclass SIMD_FP8_Dot2<string asm, SDPatternOperator op> {6609 let Uses = [FPMR, FPCR], mayLoad = 1 in {6610 def v4f16 : BaseSIMDThreeSameVectorDot<0b0, 0b0, 0b01, 0b1111, asm, ".4h", ".8b",6611 V64, v4f16, v8i8, op>;6612 def v8f16 : BaseSIMDThreeSameVectorDot<0b1, 0b0, 0b01, 0b1111, asm, ".8h", ".16b",6613 V128, v8f16, v16i8, op>;6614 }6615}6616 6617multiclass SIMD_FP8_Dot4<string asm, SDPatternOperator op> {6618 let Uses = [FPMR, FPCR], mayLoad = 1 in {6619 def v2f32 : BaseSIMDThreeSameVectorDot<0b0, 0b0, 0b00, 0b1111, asm, ".2s", ".8b",6620 V64, v2f32, v8i8, op>;6621 def v4f32 : BaseSIMDThreeSameVectorDot<0b1, 0b0, 0b00, 0b1111, asm, ".4s", ".16b",6622 V128, v4f32, v16i8, op>;6623 }6624}6625 6626let mayRaiseFPException = 1, Uses = [FPCR] in6627multiclass SIMDThreeVectorFscale<bit U, bit S, bits<3> opc,6628 string asm, SDPatternOperator OpNode> {6629 def v4f16 : BaseSIMDThreeSameVector<0, U, {S,0b10}, {0b00,opc}, V64,6630 asm, ".4h",6631 [(set (v4f16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (v4i16 V64:$Rm)))]>;6632 def v8f16 : BaseSIMDThreeSameVector<1, U, {S,0b10}, {0b00,opc}, V128,6633 asm, ".8h",6634 [(set (v8f16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (v8i16 V128:$Rm)))]>;6635 def v2f32 : BaseSIMDThreeSameVector<0, U, {S,0b01}, {0b11,opc}, V64,6636 asm, ".2s",6637 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (v2i32 V64:$Rm)))]>;6638 def v4f32 : BaseSIMDThreeSameVector<1, U, {S,0b01}, {0b11,opc}, V128,6639 asm, ".4s",6640 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (v4i32 V128:$Rm)))]>;6641 def v2f64 : BaseSIMDThreeSameVector<1, U, {S,0b11}, {0b11,opc}, V128,6642 asm, ".2d",6643 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (v2i64 V128:$Rm)))]>;6644}6645 6646//----------------------------------------------------------------------------6647// AdvSIMD two register vector instructions.6648//----------------------------------------------------------------------------6649 6650let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in6651class BaseSIMDTwoSameVector<bit Q, bit U, bits<2> size, bits<5> opcode,6652 bits<2> size2, RegisterOperand regtype, string asm,6653 string dstkind, string srckind, list<dag> pattern>6654 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm,6655 "{\t$Rd" # dstkind # ", $Rn" # srckind #6656 "|" # dstkind # "\t$Rd, $Rn}", "", pattern>,6657 Sched<[!if(Q, WriteVq, WriteVd)]> {6658 bits<5> Rd;6659 bits<5> Rn;6660 let Inst{31} = 0;6661 let Inst{30} = Q;6662 let Inst{29} = U;6663 let Inst{28-24} = 0b01110;6664 let Inst{23-22} = size;6665 let Inst{21} = 0b1;6666 let Inst{20-19} = size2;6667 let Inst{18-17} = 0b00;6668 let Inst{16-12} = opcode;6669 let Inst{11-10} = 0b10;6670 let Inst{9-5} = Rn;6671 let Inst{4-0} = Rd;6672}6673 6674let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in6675class BaseSIMDTwoSameVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,6676 bits<2> size2, RegisterOperand regtype,6677 string asm, string dstkind, string srckind,6678 list<dag> pattern>6679 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype:$Rn), asm,6680 "{\t$Rd" # dstkind # ", $Rn" # srckind #6681 "|" # dstkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>,6682 Sched<[!if(Q, WriteVq, WriteVd)]> {6683 bits<5> Rd;6684 bits<5> Rn;6685 let Inst{31} = 0;6686 let Inst{30} = Q;6687 let Inst{29} = U;6688 let Inst{28-24} = 0b01110;6689 let Inst{23-22} = size;6690 let Inst{21} = 0b1;6691 let Inst{20-19} = size2;6692 let Inst{18-17} = 0b00;6693 let Inst{16-12} = opcode;6694 let Inst{11-10} = 0b10;6695 let Inst{9-5} = Rn;6696 let Inst{4-0} = Rd;6697}6698 6699// Supports B, H, and S element sizes.6700multiclass SIMDTwoVectorBHS<bit U, bits<5> opc, string asm,6701 SDPatternOperator OpNode> {6702 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64,6703 asm, ".8b", ".8b",6704 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;6705 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128,6706 asm, ".16b", ".16b",6707 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;6708 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64,6709 asm, ".4h", ".4h",6710 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;6711 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128,6712 asm, ".8h", ".8h",6713 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;6714 def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64,6715 asm, ".2s", ".2s",6716 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;6717 def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128,6718 asm, ".4s", ".4s",6719 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;6720}6721 6722class BaseSIMDVectorLShiftLongBySize<bit Q, bits<2> size,6723 RegisterOperand regtype, string asm, string dstkind,6724 string srckind, string amount>6725 : I<(outs V128:$Rd), (ins regtype:$Rn), asm,6726 "{\t$Rd" # dstkind # ", $Rn" # srckind # ", #" # amount #6727 "|" # dstkind # "\t$Rd, $Rn, #" # amount # "}", "", []>,6728 Sched<[WriteVq]> {6729 bits<5> Rd;6730 bits<5> Rn;6731 let Inst{31} = 0;6732 let Inst{30} = Q;6733 let Inst{29-24} = 0b101110;6734 let Inst{23-22} = size;6735 let Inst{21-10} = 0b100001001110;6736 let Inst{9-5} = Rn;6737 let Inst{4-0} = Rd;6738}6739 6740multiclass SIMDVectorLShiftLongBySizeBHS {6741 let hasSideEffects = 0 in {6742 def v8i8 : BaseSIMDVectorLShiftLongBySize<0, 0b00, V64,6743 "shll", ".8h", ".8b", "8">;6744 def v16i8 : BaseSIMDVectorLShiftLongBySize<1, 0b00, V128,6745 "shll2", ".8h", ".16b", "8">;6746 def v4i16 : BaseSIMDVectorLShiftLongBySize<0, 0b01, V64,6747 "shll", ".4s", ".4h", "16">;6748 def v8i16 : BaseSIMDVectorLShiftLongBySize<1, 0b01, V128,6749 "shll2", ".4s", ".8h", "16">;6750 def v2i32 : BaseSIMDVectorLShiftLongBySize<0, 0b10, V64,6751 "shll", ".2d", ".2s", "32">;6752 def v4i32 : BaseSIMDVectorLShiftLongBySize<1, 0b10, V128,6753 "shll2", ".2d", ".4s", "32">;6754 }6755}6756 6757// Supports all element sizes.6758multiclass SIMDLongTwoVector<bit U, bits<5> opc, string asm,6759 SDPatternOperator OpNode> {6760 def v8i8_v4i16 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64,6761 asm, ".4h", ".8b",6762 [(set (v4i16 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;6763 def v16i8_v8i16 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128,6764 asm, ".8h", ".16b",6765 [(set (v8i16 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;6766 def v4i16_v2i32 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64,6767 asm, ".2s", ".4h",6768 [(set (v2i32 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;6769 def v8i16_v4i32 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128,6770 asm, ".4s", ".8h",6771 [(set (v4i32 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;6772 def v2i32_v1i64 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64,6773 asm, ".1d", ".2s",6774 [(set (v1i64 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;6775 def v4i32_v2i64 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128,6776 asm, ".2d", ".4s",6777 [(set (v2i64 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;6778}6779 6780multiclass SIMDLongTwoVectorTied<bit U, bits<5> opc, string asm,6781 SDPatternOperator OpNode> {6782 def v8i8_v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, 0b00, V64,6783 asm, ".4h", ".8b",6784 [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd),6785 (v8i8 V64:$Rn)))]>;6786 def v16i8_v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, 0b00, V128,6787 asm, ".8h", ".16b",6788 [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd),6789 (v16i8 V128:$Rn)))]>;6790 def v4i16_v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, 0b00, V64,6791 asm, ".2s", ".4h",6792 [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd),6793 (v4i16 V64:$Rn)))]>;6794 def v8i16_v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, 0b00, V128,6795 asm, ".4s", ".8h",6796 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd),6797 (v8i16 V128:$Rn)))]>;6798 def v2i32_v1i64 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, 0b00, V64,6799 asm, ".1d", ".2s",6800 [(set (v1i64 V64:$dst), (OpNode (v1i64 V64:$Rd),6801 (v2i32 V64:$Rn)))]>;6802 def v4i32_v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, 0b00, V128,6803 asm, ".2d", ".4s",6804 [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd),6805 (v4i32 V128:$Rn)))]>;6806}6807 6808// Supports all element sizes, except 1xD.6809multiclass SIMDTwoVectorBHSDTied<bit U, bits<5> opc, string asm,6810 SDPatternOperator OpNode> {6811 def v8i8 : BaseSIMDTwoSameVectorTied<0, U, 0b00, opc, 0b00, V64,6812 asm, ".8b", ".8b",6813 [(set (v8i8 V64:$dst), (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn)))]>;6814 def v16i8 : BaseSIMDTwoSameVectorTied<1, U, 0b00, opc, 0b00, V128,6815 asm, ".16b", ".16b",6816 [(set (v16i8 V128:$dst), (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>;6817 def v4i16 : BaseSIMDTwoSameVectorTied<0, U, 0b01, opc, 0b00, V64,6818 asm, ".4h", ".4h",6819 [(set (v4i16 V64:$dst), (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn)))]>;6820 def v8i16 : BaseSIMDTwoSameVectorTied<1, U, 0b01, opc, 0b00, V128,6821 asm, ".8h", ".8h",6822 [(set (v8i16 V128:$dst), (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn)))]>;6823 def v2i32 : BaseSIMDTwoSameVectorTied<0, U, 0b10, opc, 0b00, V64,6824 asm, ".2s", ".2s",6825 [(set (v2i32 V64:$dst), (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn)))]>;6826 def v4i32 : BaseSIMDTwoSameVectorTied<1, U, 0b10, opc, 0b00, V128,6827 asm, ".4s", ".4s",6828 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>;6829 def v2i64 : BaseSIMDTwoSameVectorTied<1, U, 0b11, opc, 0b00, V128,6830 asm, ".2d", ".2d",6831 [(set (v2i64 V128:$dst), (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn)))]>;6832}6833 6834multiclass SIMDTwoVectorBHSD<bit U, bits<5> opc, string asm,6835 SDPatternOperator OpNode = null_frag> {6836 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64,6837 asm, ".8b", ".8b",6838 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;6839 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128,6840 asm, ".16b", ".16b",6841 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;6842 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64,6843 asm, ".4h", ".4h",6844 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;6845 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128,6846 asm, ".8h", ".8h",6847 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;6848 def v2i32 : BaseSIMDTwoSameVector<0, U, 0b10, opc, 0b00, V64,6849 asm, ".2s", ".2s",6850 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;6851 def v4i32 : BaseSIMDTwoSameVector<1, U, 0b10, opc, 0b00, V128,6852 asm, ".4s", ".4s",6853 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;6854 def v2i64 : BaseSIMDTwoSameVector<1, U, 0b11, opc, 0b00, V128,6855 asm, ".2d", ".2d",6856 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>;6857}6858 6859 6860// Supports only B element sizes.6861multiclass SIMDTwoVectorB<bit U, bits<2> size, bits<5> opc, string asm,6862 SDPatternOperator OpNode> {6863 def v8i8 : BaseSIMDTwoSameVector<0, U, size, opc, 0b00, V64,6864 asm, ".8b", ".8b",6865 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn)))]>;6866 def v16i8 : BaseSIMDTwoSameVector<1, U, size, opc, 0b00, V128,6867 asm, ".16b", ".16b",6868 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;6869 6870}6871 6872// Supports only B and H element sizes.6873multiclass SIMDTwoVectorBH<bit U, bits<5> opc, string asm,6874 SDPatternOperator OpNode> {6875 def v8i8 : BaseSIMDTwoSameVector<0, U, 0b00, opc, 0b00, V64,6876 asm, ".8b", ".8b",6877 [(set (v8i8 V64:$Rd), (OpNode V64:$Rn))]>;6878 def v16i8 : BaseSIMDTwoSameVector<1, U, 0b00, opc, 0b00, V128,6879 asm, ".16b", ".16b",6880 [(set (v16i8 V128:$Rd), (OpNode V128:$Rn))]>;6881 def v4i16 : BaseSIMDTwoSameVector<0, U, 0b01, opc, 0b00, V64,6882 asm, ".4h", ".4h",6883 [(set (v4i16 V64:$Rd), (OpNode V64:$Rn))]>;6884 def v8i16 : BaseSIMDTwoSameVector<1, U, 0b01, opc, 0b00, V128,6885 asm, ".8h", ".8h",6886 [(set (v8i16 V128:$Rd), (OpNode V128:$Rn))]>;6887}6888 6889// Supports H, S and D element sizes, uses high bit of the size field6890// as an extra opcode bit.6891multiclass SIMDTwoVectorFP<bit U, bit S, bits<5> opc, string asm,6892 SDPatternOperator OpNode,6893 int fpexceptions = 1> {6894 let mayRaiseFPException = fpexceptions, Uses = !if(fpexceptions,[FPCR],[]<Register>) in {6895 let Predicates = [HasNEON, HasFullFP16] in {6896 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64,6897 asm, ".4h", ".4h",6898 [(set (v4f16 V64:$Rd), (OpNode (v4f16 V64:$Rn)))]>;6899 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128,6900 asm, ".8h", ".8h",6901 [(set (v8f16 V128:$Rd), (OpNode (v8f16 V128:$Rn)))]>;6902 } // Predicates = [HasNEON, HasFullFP16]6903 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64,6904 asm, ".2s", ".2s",6905 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>;6906 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128,6907 asm, ".4s", ".4s",6908 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>;6909 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128,6910 asm, ".2d", ".2d",6911 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>;6912 }6913}6914 6915multiclass SIMDTwoVectorFPNoException<bit U, bit S, bits<5> opc, string asm,6916 SDPatternOperator OpNode>6917 : SIMDTwoVectorFP<U, S, opc, asm, OpNode, 0>;6918 6919// Supports only S and D element sizes6920let mayRaiseFPException = 1, Uses = [FPCR] in6921multiclass SIMDTwoVectorSD<bit U, bits<5> opc, string asm,6922 SDPatternOperator OpNode = null_frag> {6923 6924 def v2f32 : BaseSIMDTwoSameVector<0, U, 00, opc, 0b00, V64,6925 asm, ".2s", ".2s",6926 [(set (v2f32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>;6927 def v4f32 : BaseSIMDTwoSameVector<1, U, 00, opc, 0b00, V128,6928 asm, ".4s", ".4s",6929 [(set (v4f32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>;6930 def v2f64 : BaseSIMDTwoSameVector<1, U, 01, opc, 0b00, V128,6931 asm, ".2d", ".2d",6932 [(set (v2f64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>;6933}6934 6935multiclass FRIntNNTVector<bit U, bit op, string asm,6936 SDPatternOperator OpNode = null_frag> :6937 SIMDTwoVectorSD<U, {0b1111,op}, asm, OpNode>;6938 6939// Supports only S element size.6940multiclass SIMDTwoVectorS<bit U, bit S, bits<5> opc, string asm,6941 SDPatternOperator OpNode> {6942 def v2i32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64,6943 asm, ".2s", ".2s",6944 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;6945 def v4i32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128,6946 asm, ".4s", ".4s",6947 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;6948}6949 6950let mayRaiseFPException = 1, Uses = [FPCR] in6951multiclass SIMDTwoVectorFPToInt<bit U, bit S, bits<5> opc, string asm,6952 SDPatternOperator OpNode> {6953 let Predicates = [HasNEON, HasFullFP16] in {6954 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64,6955 asm, ".4h", ".4h",6956 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn)))]>;6957 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128,6958 asm, ".8h", ".8h",6959 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn)))]>;6960 } // Predicates = [HasNEON, HasFullFP16]6961 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64,6962 asm, ".2s", ".2s",6963 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn)))]>;6964 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128,6965 asm, ".4s", ".4s",6966 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn)))]>;6967 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128,6968 asm, ".2d", ".2d",6969 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn)))]>;6970}6971 6972let mayRaiseFPException = 1, Uses = [FPCR] in6973multiclass SIMDTwoVectorIntToFP<bit U, bit S, bits<5> opc, string asm,6974 SDPatternOperator OpNode> {6975 let Predicates = [HasNEON, HasFullFP16] in {6976 def v4f16 : BaseSIMDTwoSameVector<0, U, {S,1}, opc, 0b11, V64,6977 asm, ".4h", ".4h",6978 [(set (v4f16 V64:$Rd), (OpNode (v4i16 V64:$Rn)))]>;6979 def v8f16 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b11, V128,6980 asm, ".8h", ".8h",6981 [(set (v8f16 V128:$Rd), (OpNode (v8i16 V128:$Rn)))]>;6982 } // Predicates = [HasNEON, HasFullFP16]6983 def v2f32 : BaseSIMDTwoSameVector<0, U, {S,0}, opc, 0b00, V64,6984 asm, ".2s", ".2s",6985 [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn)))]>;6986 def v4f32 : BaseSIMDTwoSameVector<1, U, {S,0}, opc, 0b00, V128,6987 asm, ".4s", ".4s",6988 [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn)))]>;6989 def v2f64 : BaseSIMDTwoSameVector<1, U, {S,1}, opc, 0b00, V128,6990 asm, ".2d", ".2d",6991 [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn)))]>;6992}6993 6994let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in6995class BaseSIMDMixedTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode,6996 RegisterOperand inreg, RegisterOperand outreg,6997 string asm, string outkind, string inkind,6998 list<dag> pattern>6999 : I<(outs outreg:$Rd), (ins inreg:$Rn), asm,7000 "{\t$Rd" # outkind # ", $Rn" # inkind #7001 "|" # outkind # "\t$Rd, $Rn}", "", pattern>,7002 Sched<[WriteVq]> {7003 bits<5> Rd;7004 bits<5> Rn;7005 let Inst{31} = 0;7006 let Inst{30} = Q;7007 let Inst{29} = U;7008 let Inst{28-24} = 0b01110;7009 let Inst{23-22} = size;7010 let Inst{21-17} = 0b10000;7011 let Inst{16-12} = opcode;7012 let Inst{11-10} = 0b10;7013 let Inst{9-5} = Rn;7014 let Inst{4-0} = Rd;7015}7016 7017let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in7018class BaseSIMDMixedTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,7019 RegisterOperand inreg, RegisterOperand outreg,7020 string asm, string outkind, string inkind,7021 list<dag> pattern>7022 : I<(outs outreg:$dst), (ins outreg:$Rd, inreg:$Rn), asm,7023 "{\t$Rd" # outkind # ", $Rn" # inkind #7024 "|" # outkind # "\t$Rd, $Rn}", "$Rd = $dst", pattern>,7025 Sched<[WriteVq]> {7026 bits<5> Rd;7027 bits<5> Rn;7028 let Inst{31} = 0;7029 let Inst{30} = Q;7030 let Inst{29} = U;7031 let Inst{28-24} = 0b01110;7032 let Inst{23-22} = size;7033 let Inst{21-17} = 0b10000;7034 let Inst{16-12} = opcode;7035 let Inst{11-10} = 0b10;7036 let Inst{9-5} = Rn;7037 let Inst{4-0} = Rd;7038}7039 7040multiclass SIMDMixedTwoVector<bit U, bits<5> opc, string asm,7041 SDPatternOperator OpNode> {7042 def v8i8 : BaseSIMDMixedTwoVector<0, U, 0b00, opc, V128, V64,7043 asm, ".8b", ".8h",7044 [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn)))]>;7045 def v16i8 : BaseSIMDMixedTwoVectorTied<1, U, 0b00, opc, V128, V128,7046 asm#"2", ".16b", ".8h", []>;7047 def v4i16 : BaseSIMDMixedTwoVector<0, U, 0b01, opc, V128, V64,7048 asm, ".4h", ".4s",7049 [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn)))]>;7050 def v8i16 : BaseSIMDMixedTwoVectorTied<1, U, 0b01, opc, V128, V128,7051 asm#"2", ".8h", ".4s", []>;7052 def v2i32 : BaseSIMDMixedTwoVector<0, U, 0b10, opc, V128, V64,7053 asm, ".2s", ".2d",7054 [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn)))]>;7055 def v4i32 : BaseSIMDMixedTwoVectorTied<1, U, 0b10, opc, V128, V128,7056 asm#"2", ".4s", ".2d", []>;7057 7058 def : Pat<(concat_vectors (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn))),7059 (!cast<Instruction>(NAME # "v16i8")7060 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;7061 def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn))),7062 (!cast<Instruction>(NAME # "v8i16")7063 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;7064 def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn))),7065 (!cast<Instruction>(NAME # "v4i32")7066 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;7067}7068 7069//----------------------------------------------------------------------------7070// FP8 Advanced SIMD two-register miscellaneous7071//----------------------------------------------------------------------------7072multiclass SIMD_FP8_CVTL<bits<2>sz, string asm, ValueType dty, SDPatternOperator Op> {7073 let Uses=[FPMR, FPCR], mayLoad = 1 in {7074 def NAME : BaseSIMDMixedTwoVector<0b0, 0b1, sz, 0b10111, V64, V128,7075 asm, ".8h", ".8b", []>;7076 def NAME#2 : BaseSIMDMixedTwoVector<0b1, 0b1, sz, 0b10111, V128, V128,7077 asm#2, ".8h", ".16b", []>;7078 }7079 def : Pat<(dty (Op (v8i8 V64:$Rn))),7080 (!cast<Instruction>(NAME) V64:$Rn)>;7081 7082 def : Pat<(dty (Op (v16i8 V128:$Rn))),7083 (!cast<Instruction>(NAME#2) V128:$Rn)>;7084}7085 7086class BaseSIMDCmpTwoVector<bit Q, bit U, bits<2> size, bits<2> size2,7087 bits<5> opcode, RegisterOperand regtype, string asm,7088 string kind, string zero, ValueType dty,7089 ValueType sty, SDPatternOperator OpNode>7090 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm,7091 "{\t$Rd" # kind # ", $Rn" # kind # ", #" # zero #7092 "|" # kind # "\t$Rd, $Rn, #" # zero # "}", "",7093 [(set (dty regtype:$Rd), (OpNode (sty regtype:$Rn)))]>,7094 Sched<[!if(Q, WriteVq, WriteVd)]> {7095 bits<5> Rd;7096 bits<5> Rn;7097 let Inst{31} = 0;7098 let Inst{30} = Q;7099 let Inst{29} = U;7100 let Inst{28-24} = 0b01110;7101 let Inst{23-22} = size;7102 let Inst{21} = 0b1;7103 let Inst{20-19} = size2;7104 let Inst{18-17} = 0b00;7105 let Inst{16-12} = opcode;7106 let Inst{11-10} = 0b10;7107 let Inst{9-5} = Rn;7108 let Inst{4-0} = Rd;7109}7110 7111// Comparisons support all element sizes, except 1xD.7112multiclass SIMDCmpTwoVector<bit U, bits<5> opc, string asm,7113 SDPatternOperator OpNode> {7114 def v8i8rz : BaseSIMDCmpTwoVector<0, U, 0b00, 0b00, opc, V64,7115 asm, ".8b", "0",7116 v8i8, v8i8, OpNode>;7117 def v16i8rz : BaseSIMDCmpTwoVector<1, U, 0b00, 0b00, opc, V128,7118 asm, ".16b", "0",7119 v16i8, v16i8, OpNode>;7120 def v4i16rz : BaseSIMDCmpTwoVector<0, U, 0b01, 0b00, opc, V64,7121 asm, ".4h", "0",7122 v4i16, v4i16, OpNode>;7123 def v8i16rz : BaseSIMDCmpTwoVector<1, U, 0b01, 0b00, opc, V128,7124 asm, ".8h", "0",7125 v8i16, v8i16, OpNode>;7126 def v2i32rz : BaseSIMDCmpTwoVector<0, U, 0b10, 0b00, opc, V64,7127 asm, ".2s", "0",7128 v2i32, v2i32, OpNode>;7129 def v4i32rz : BaseSIMDCmpTwoVector<1, U, 0b10, 0b00, opc, V128,7130 asm, ".4s", "0",7131 v4i32, v4i32, OpNode>;7132 def v2i64rz : BaseSIMDCmpTwoVector<1, U, 0b11, 0b00, opc, V128,7133 asm, ".2d", "0",7134 v2i64, v2i64, OpNode>;7135}7136 7137// FP Comparisons support only S and D element sizes (and H for v8.2a).7138multiclass SIMDFPCmpTwoVector<bit U, bit S, bits<5> opc,7139 string asm, SDPatternOperator OpNode> {7140 7141 let mayRaiseFPException = 1, Uses = [FPCR] in {7142 let Predicates = [HasNEON, HasFullFP16] in {7143 def v4i16rz : BaseSIMDCmpTwoVector<0, U, {S,1}, 0b11, opc, V64,7144 asm, ".4h", "0.0",7145 v4i16, v4f16, OpNode>;7146 def v8i16rz : BaseSIMDCmpTwoVector<1, U, {S,1}, 0b11, opc, V128,7147 asm, ".8h", "0.0",7148 v8i16, v8f16, OpNode>;7149 } // Predicates = [HasNEON, HasFullFP16]7150 def v2i32rz : BaseSIMDCmpTwoVector<0, U, {S,0}, 0b00, opc, V64,7151 asm, ".2s", "0.0",7152 v2i32, v2f32, OpNode>;7153 def v4i32rz : BaseSIMDCmpTwoVector<1, U, {S,0}, 0b00, opc, V128,7154 asm, ".4s", "0.0",7155 v4i32, v4f32, OpNode>;7156 def v2i64rz : BaseSIMDCmpTwoVector<1, U, {S,1}, 0b00, opc, V128,7157 asm, ".2d", "0.0",7158 v2i64, v2f64, OpNode>;7159 }7160 7161 let Predicates = [HasNEON, HasFullFP16] in {7162 def : InstAlias<asm # "\t$Vd.4h, $Vn.4h, #0",7163 (!cast<Instruction>(NAME # v4i16rz) V64:$Vd, V64:$Vn), 0>;7164 def : InstAlias<asm # "\t$Vd.8h, $Vn.8h, #0",7165 (!cast<Instruction>(NAME # v8i16rz) V128:$Vd, V128:$Vn), 0>;7166 }7167 def : InstAlias<asm # "\t$Vd.2s, $Vn.2s, #0",7168 (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>;7169 def : InstAlias<asm # "\t$Vd.4s, $Vn.4s, #0",7170 (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>;7171 def : InstAlias<asm # "\t$Vd.2d, $Vn.2d, #0",7172 (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>;7173 let Predicates = [HasNEON, HasFullFP16] in {7174 def : InstAlias<asm # ".4h\t$Vd, $Vn, #0",7175 (!cast<Instruction>(NAME # v4i16rz) V64:$Vd, V64:$Vn), 0>;7176 def : InstAlias<asm # ".8h\t$Vd, $Vn, #0",7177 (!cast<Instruction>(NAME # v8i16rz) V128:$Vd, V128:$Vn), 0>;7178 }7179 def : InstAlias<asm # ".2s\t$Vd, $Vn, #0",7180 (!cast<Instruction>(NAME # v2i32rz) V64:$Vd, V64:$Vn), 0>;7181 def : InstAlias<asm # ".4s\t$Vd, $Vn, #0",7182 (!cast<Instruction>(NAME # v4i32rz) V128:$Vd, V128:$Vn), 0>;7183 def : InstAlias<asm # ".2d\t$Vd, $Vn, #0",7184 (!cast<Instruction>(NAME # v2i64rz) V128:$Vd, V128:$Vn), 0>;7185}7186 7187let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in7188class BaseSIMDFPCvtTwoVector<bit Q, bit U, bits<2> size, bits<5> opcode,7189 RegisterOperand outtype, RegisterOperand intype,7190 string asm, string VdTy, string VnTy,7191 list<dag> pattern>7192 : I<(outs outtype:$Rd), (ins intype:$Rn), asm,7193 !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "", pattern>,7194 Sched<[WriteVq]> {7195 bits<5> Rd;7196 bits<5> Rn;7197 let Inst{31} = 0;7198 let Inst{30} = Q;7199 let Inst{29} = U;7200 let Inst{28-24} = 0b01110;7201 let Inst{23-22} = size;7202 let Inst{21-17} = 0b10000;7203 let Inst{16-12} = opcode;7204 let Inst{11-10} = 0b10;7205 let Inst{9-5} = Rn;7206 let Inst{4-0} = Rd;7207}7208 7209let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in7210class BaseSIMDFPCvtTwoVectorTied<bit Q, bit U, bits<2> size, bits<5> opcode,7211 RegisterOperand outtype, RegisterOperand intype,7212 string asm, string VdTy, string VnTy,7213 list<dag> pattern>7214 : I<(outs outtype:$dst), (ins outtype:$Rd, intype:$Rn), asm,7215 !strconcat("\t$Rd", VdTy, ", $Rn", VnTy), "$Rd = $dst", pattern>,7216 Sched<[WriteVq]> {7217 bits<5> Rd;7218 bits<5> Rn;7219 let Inst{31} = 0;7220 let Inst{30} = Q;7221 let Inst{29} = U;7222 let Inst{28-24} = 0b01110;7223 let Inst{23-22} = size;7224 let Inst{21-17} = 0b10000;7225 let Inst{16-12} = opcode;7226 let Inst{11-10} = 0b10;7227 let Inst{9-5} = Rn;7228 let Inst{4-0} = Rd;7229}7230 7231multiclass SIMDFPWidenTwoVector<bit U, bit S, bits<5> opc, string asm> {7232 def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V128, V64,7233 asm, ".4s", ".4h", []>;7234 def v8i16 : BaseSIMDFPCvtTwoVector<1, U, {S,0}, opc, V128, V128,7235 asm#"2", ".4s", ".8h", []>;7236 def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V128, V64,7237 asm, ".2d", ".2s", []>;7238 def v4i32 : BaseSIMDFPCvtTwoVector<1, U, {S,1}, opc, V128, V128,7239 asm#"2", ".2d", ".4s", []>;7240}7241 7242multiclass SIMDFPNarrowTwoVector<bit U, bit S, bits<5> opc, string asm> {7243 def v4i16 : BaseSIMDFPCvtTwoVector<0, U, {S,0}, opc, V64, V128,7244 asm, ".4h", ".4s", []>;7245 def v8i16 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,0}, opc, V128, V128,7246 asm#"2", ".8h", ".4s", []>;7247 def v2i32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128,7248 asm, ".2s", ".2d", []>;7249 def v4i32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128,7250 asm#"2", ".4s", ".2d", []>;7251}7252 7253multiclass SIMDFPInexactCvtTwoVector<bit U, bit S, bits<5> opc, string asm,7254 SDPatternOperator OpNode> {7255 def v2f32 : BaseSIMDFPCvtTwoVector<0, U, {S,1}, opc, V64, V128,7256 asm, ".2s", ".2d",7257 [(set (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn)))]>;7258 def v4f32 : BaseSIMDFPCvtTwoVectorTied<1, U, {S,1}, opc, V128, V128,7259 asm#"2", ".4s", ".2d", []>;7260 7261 def : Pat<(concat_vectors (v2f32 V64:$Rd), (OpNode (v2f64 V128:$Rn))),7262 (!cast<Instruction>(NAME # "v4f32")7263 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub), V128:$Rn)>;7264}7265 7266//----------------------------------------------------------------------------7267// AdvSIMD three register different-size vector instructions.7268//----------------------------------------------------------------------------7269 7270let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in7271class BaseSIMDDifferentThreeVector<bit U, bits<3> size, bits<4> opcode,7272 RegisterOperand outtype, RegisterOperand intype1,7273 RegisterOperand intype2, string asm,7274 string outkind, string inkind1, string inkind2,7275 list<dag> pattern>7276 : I<(outs outtype:$Rd), (ins intype1:$Rn, intype2:$Rm), asm,7277 "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 #7278 "|" # outkind # "\t$Rd, $Rn, $Rm}", "", pattern>,7279 Sched<[WriteVq]> {7280 bits<5> Rd;7281 bits<5> Rn;7282 bits<5> Rm;7283 let Inst{31} = 0;7284 let Inst{30} = size{0};7285 let Inst{29} = U;7286 let Inst{28-24} = 0b01110;7287 let Inst{23-22} = size{2-1};7288 let Inst{21} = 1;7289 let Inst{20-16} = Rm;7290 let Inst{15-12} = opcode;7291 let Inst{11-10} = 0b00;7292 let Inst{9-5} = Rn;7293 let Inst{4-0} = Rd;7294}7295 7296let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in7297class BaseSIMDDifferentThreeVectorTied<bit U, bits<3> size, bits<4> opcode,7298 RegisterOperand outtype, RegisterOperand intype1,7299 RegisterOperand intype2, string asm,7300 string outkind, string inkind1, string inkind2,7301 list<dag> pattern>7302 : I<(outs outtype:$dst), (ins outtype:$Rd, intype1:$Rn, intype2:$Rm), asm,7303 "{\t$Rd" # outkind # ", $Rn" # inkind1 # ", $Rm" # inkind2 #7304 "|" # outkind # "\t$Rd, $Rn, $Rm}", "$Rd = $dst", pattern>,7305 Sched<[WriteVq]> {7306 bits<5> Rd;7307 bits<5> Rn;7308 bits<5> Rm;7309 let Inst{31} = 0;7310 let Inst{30} = size{0};7311 let Inst{29} = U;7312 let Inst{28-24} = 0b01110;7313 let Inst{23-22} = size{2-1};7314 let Inst{21} = 1;7315 let Inst{20-16} = Rm;7316 let Inst{15-12} = opcode;7317 let Inst{11-10} = 0b00;7318 let Inst{9-5} = Rn;7319 let Inst{4-0} = Rd;7320}7321 7322// FIXME: TableGen doesn't know how to deal with expanded types that also7323// change the element count (in this case, placing the results in7324// the high elements of the result register rather than the low7325// elements). Until that's fixed, we can't code-gen those.7326multiclass SIMDNarrowThreeVectorBHS<bit U, bits<4> opc, string asm,7327 Intrinsic IntOp> {7328 def v8i16_v8i8 : BaseSIMDDifferentThreeVector<U, 0b000, opc,7329 V64, V128, V128,7330 asm, ".8b", ".8h", ".8h",7331 [(set (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn), (v8i16 V128:$Rm)))]>;7332 def v8i16_v16i8 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc,7333 V128, V128, V128,7334 asm#"2", ".16b", ".8h", ".8h",7335 []>;7336 def v4i32_v4i16 : BaseSIMDDifferentThreeVector<U, 0b010, opc,7337 V64, V128, V128,7338 asm, ".4h", ".4s", ".4s",7339 [(set (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn), (v4i32 V128:$Rm)))]>;7340 def v4i32_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,7341 V128, V128, V128,7342 asm#"2", ".8h", ".4s", ".4s",7343 []>;7344 def v2i64_v2i32 : BaseSIMDDifferentThreeVector<U, 0b100, opc,7345 V64, V128, V128,7346 asm, ".2s", ".2d", ".2d",7347 [(set (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn), (v2i64 V128:$Rm)))]>;7348 def v2i64_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,7349 V128, V128, V128,7350 asm#"2", ".4s", ".2d", ".2d",7351 []>;7352 7353 7354 // Patterns for the '2' variants involve INSERT_SUBREG, which you can't put in7355 // a version attached to an instruction.7356 def : Pat<(concat_vectors (v8i8 V64:$Rd), (IntOp (v8i16 V128:$Rn),7357 (v8i16 V128:$Rm))),7358 (!cast<Instruction>(NAME # "v8i16_v16i8")7359 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),7360 V128:$Rn, V128:$Rm)>;7361 def : Pat<(concat_vectors (v4i16 V64:$Rd), (IntOp (v4i32 V128:$Rn),7362 (v4i32 V128:$Rm))),7363 (!cast<Instruction>(NAME # "v4i32_v8i16")7364 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),7365 V128:$Rn, V128:$Rm)>;7366 def : Pat<(concat_vectors (v2i32 V64:$Rd), (IntOp (v2i64 V128:$Rn),7367 (v2i64 V128:$Rm))),7368 (!cast<Instruction>(NAME # "v2i64_v4i32")7369 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),7370 V128:$Rn, V128:$Rm)>;7371}7372 7373multiclass SIMDDifferentThreeVectorBD<bit U, bits<4> opc, string asm,7374 SDPatternOperator OpNode> {7375 def v8i8 : BaseSIMDDifferentThreeVector<U, 0b000, opc,7376 V128, V64, V64,7377 asm, ".8h", ".8b", ".8b",7378 [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;7379 def v16i8 : BaseSIMDDifferentThreeVector<U, 0b001, opc,7380 V128, V128, V128,7381 asm#"2", ".8h", ".16b", ".16b",7382 [(set (v8i16 V128:$Rd), (OpNode (v8i8 (extract_high_v16i8 (v16i8 V128:$Rn))),7383 (v8i8 (extract_high_v16i8 (v16i8 V128:$Rm)))))]>;7384 let Predicates = [HasAES] in {7385 def v1i64 : BaseSIMDDifferentThreeVector<U, 0b110, opc,7386 V128, V64, V64,7387 asm, ".1q", ".1d", ".1d",7388 [(set (v16i8 V128:$Rd), (OpNode (v1i64 V64:$Rn), (v1i64 V64:$Rm)))]>;7389 def v2i64 : BaseSIMDDifferentThreeVector<U, 0b111, opc,7390 V128, V128, V128,7391 asm#"2", ".1q", ".2d", ".2d",7392 [(set (v16i8 V128:$Rd), (OpNode (extract_high_v2i64 (v2i64 V128:$Rn)),7393 (extract_high_v2i64 (v2i64 V128:$Rm))))]>;7394 }7395}7396 7397multiclass SIMDLongThreeVectorHS<bit U, bits<4> opc, string asm,7398 SDPatternOperator OpNode> {7399 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc,7400 V128, V64, V64,7401 asm, ".4s", ".4h", ".4h",7402 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;7403 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc,7404 V128, V128, V128,7405 asm#"2", ".4s", ".8h", ".8h",7406 [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 (v8i16 V128:$Rn)),7407 (extract_high_v8i16 (v8i16 V128:$Rm))))]>;7408 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc,7409 V128, V64, V64,7410 asm, ".2d", ".2s", ".2s",7411 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;7412 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc,7413 V128, V128, V128,7414 asm#"2", ".2d", ".4s", ".4s",7415 [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 (v4i32 V128:$Rn)),7416 (extract_high_v4i32 (v4i32 V128:$Rm))))]>;7417}7418 7419let isCommutable = 1 in7420multiclass SIMDLongThreeVectorBHS<bit U, bits<4> opc, string asm,7421 SDPatternOperator OpNode = null_frag> {7422 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc,7423 V128, V64, V64,7424 asm, ".8h", ".8b", ".8b",7425 [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;7426 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc,7427 V128, V128, V128,7428 asm#"2", ".8h", ".16b", ".16b",7429 [(set (v8i16 V128:$Rd), (OpNode (extract_high_v16i8 (v16i8 V128:$Rn)),7430 (extract_high_v16i8 (v16i8 V128:$Rm))))]>;7431 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc,7432 V128, V64, V64,7433 asm, ".4s", ".4h", ".4h",7434 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;7435 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc,7436 V128, V128, V128,7437 asm#"2", ".4s", ".8h", ".8h",7438 [(set (v4i32 V128:$Rd), (OpNode (extract_high_v8i16 (v8i16 V128:$Rn)),7439 (extract_high_v8i16 (v8i16 V128:$Rm))))]>;7440 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc,7441 V128, V64, V64,7442 asm, ".2d", ".2s", ".2s",7443 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;7444 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc,7445 V128, V128, V128,7446 asm#"2", ".2d", ".4s", ".4s",7447 [(set (v2i64 V128:$Rd), (OpNode (extract_high_v4i32 (v4i32 V128:$Rn)),7448 (extract_high_v4i32 (v4i32 V128:$Rm))))]>;7449}7450 7451multiclass SIMDLongThreeVectorTiedBHS<bit U, bits<4> opc,7452 string asm,7453 SDPatternOperator OpNode> {7454 def v8i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b000, opc,7455 V128, V64, V64,7456 asm, ".8h", ".8b", ".8b",7457 [(set (v8i16 V128:$dst),7458 (OpNode (v8i16 V128:$Rd), (v8i8 V64:$Rn), (v8i8 V64:$Rm)))]>;7459 def v16i8_v8i16 : BaseSIMDDifferentThreeVectorTied<U, 0b001, opc,7460 V128, V128, V128,7461 asm#"2", ".8h", ".16b", ".16b",7462 [(set (v8i16 V128:$dst),7463 (OpNode (v8i16 V128:$Rd),7464 (extract_high_v16i8 (v16i8 V128:$Rn)),7465 (extract_high_v16i8 (v16i8 V128:$Rm))))]>;7466 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc,7467 V128, V64, V64,7468 asm, ".4s", ".4h", ".4h",7469 [(set (v4i32 V128:$dst),7470 (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm)))]>;7471 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,7472 V128, V128, V128,7473 asm#"2", ".4s", ".8h", ".8h",7474 [(set (v4i32 V128:$dst),7475 (OpNode (v4i32 V128:$Rd),7476 (extract_high_v8i16 (v8i16 V128:$Rn)),7477 (extract_high_v8i16 (v8i16 V128:$Rm))))]>;7478 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc,7479 V128, V64, V64,7480 asm, ".2d", ".2s", ".2s",7481 [(set (v2i64 V128:$dst),7482 (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm)))]>;7483 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,7484 V128, V128, V128,7485 asm#"2", ".2d", ".4s", ".4s",7486 [(set (v2i64 V128:$dst),7487 (OpNode (v2i64 V128:$Rd),7488 (extract_high_v4i32 (v4i32 V128:$Rn)),7489 (extract_high_v4i32 (v4i32 V128:$Rm))))]>;7490}7491 7492multiclass SIMDLongThreeVectorSQDMLXTiedHS<bit U, bits<4> opc, string asm,7493 SDPatternOperator Accum> {7494 def v4i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b010, opc,7495 V128, V64, V64,7496 asm, ".4s", ".4h", ".4h",7497 [(set (v4i32 V128:$dst),7498 (Accum (v4i32 V128:$Rd),7499 (v4i32 (int_aarch64_neon_sqdmull (v4i16 V64:$Rn),7500 (v4i16 V64:$Rm)))))]>;7501 def v8i16_v4i32 : BaseSIMDDifferentThreeVectorTied<U, 0b011, opc,7502 V128, V128, V128,7503 asm#"2", ".4s", ".8h", ".8h",7504 [(set (v4i32 V128:$dst),7505 (Accum (v4i32 V128:$Rd),7506 (v4i32 (int_aarch64_neon_sqdmull (extract_high_v8i16 (v8i16 V128:$Rn)),7507 (extract_high_v8i16 (v8i16 V128:$Rm))))))]>;7508 def v2i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b100, opc,7509 V128, V64, V64,7510 asm, ".2d", ".2s", ".2s",7511 [(set (v2i64 V128:$dst),7512 (Accum (v2i64 V128:$Rd),7513 (v2i64 (int_aarch64_neon_sqdmull (v2i32 V64:$Rn),7514 (v2i32 V64:$Rm)))))]>;7515 def v4i32_v2i64 : BaseSIMDDifferentThreeVectorTied<U, 0b101, opc,7516 V128, V128, V128,7517 asm#"2", ".2d", ".4s", ".4s",7518 [(set (v2i64 V128:$dst),7519 (Accum (v2i64 V128:$Rd),7520 (v2i64 (int_aarch64_neon_sqdmull (extract_high_v4i32 (v4i32 V128:$Rn)),7521 (extract_high_v4i32 (v4i32 V128:$Rm))))))]>;7522}7523 7524multiclass SIMDWideThreeVectorBHS<bit U, bits<4> opc, string asm,7525 SDPatternOperator OpNode> {7526 def v8i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b000, opc,7527 V128, V128, V64,7528 asm, ".8h", ".8h", ".8b",7529 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (v8i8 V64:$Rm)))]>;7530 def v16i8_v8i16 : BaseSIMDDifferentThreeVector<U, 0b001, opc,7531 V128, V128, V128,7532 asm#"2", ".8h", ".8h", ".16b",7533 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn),7534 (extract_high_v16i8 (v16i8 V128:$Rm))))]>;7535 def v4i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b010, opc,7536 V128, V128, V64,7537 asm, ".4s", ".4s", ".4h",7538 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (v4i16 V64:$Rm)))]>;7539 def v8i16_v4i32 : BaseSIMDDifferentThreeVector<U, 0b011, opc,7540 V128, V128, V128,7541 asm#"2", ".4s", ".4s", ".8h",7542 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn),7543 (extract_high_v8i16 (v8i16 V128:$Rm))))]>;7544 def v2i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b100, opc,7545 V128, V128, V64,7546 asm, ".2d", ".2d", ".2s",7547 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (v2i32 V64:$Rm)))]>;7548 def v4i32_v2i64 : BaseSIMDDifferentThreeVector<U, 0b101, opc,7549 V128, V128, V128,7550 asm#"2", ".2d", ".2d", ".4s",7551 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn),7552 (extract_high_v4i32 (v4i32 V128:$Rm))))]>;7553}7554 7555//----------------------------------------------------------------------------7556// AdvSIMD bitwise extract from vector7557//----------------------------------------------------------------------------7558 7559class BaseSIMDBitwiseExtract<bit size, RegisterOperand regtype, ValueType vty,7560 string asm, string kind>7561 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, i32imm:$imm), asm,7562 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $imm" #7563 "|" # kind # "\t$Rd, $Rn, $Rm, $imm}", "",7564 [(set (vty regtype:$Rd),7565 (AArch64ext regtype:$Rn, regtype:$Rm, (i32 imm:$imm)))]>,7566 Sched<[!if(size, WriteVq, WriteVd)]> {7567 bits<5> Rd;7568 bits<5> Rn;7569 bits<5> Rm;7570 bits<4> imm;7571 let Inst{31} = 0;7572 let Inst{30} = size;7573 let Inst{29-21} = 0b101110000;7574 let Inst{20-16} = Rm;7575 let Inst{15} = 0;7576 let Inst{14-11} = imm;7577 let Inst{10} = 0;7578 let Inst{9-5} = Rn;7579 let Inst{4-0} = Rd;7580}7581 7582 7583multiclass SIMDBitwiseExtract<string asm> {7584 def v8i8 : BaseSIMDBitwiseExtract<0, V64, v8i8, asm, ".8b"> {7585 let imm{3} = 0;7586 }7587 def v16i8 : BaseSIMDBitwiseExtract<1, V128, v16i8, asm, ".16b">;7588}7589 7590//----------------------------------------------------------------------------7591// AdvSIMD zip vector7592//----------------------------------------------------------------------------7593 7594class BaseSIMDZipVector<bits<3> size, bits<3> opc, RegisterOperand regtype,7595 string asm, string kind, SDNode OpNode, ValueType valty>7596 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm,7597 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind #7598 "|" # kind # "\t$Rd, $Rn, $Rm}", "",7599 [(set (valty regtype:$Rd), (OpNode regtype:$Rn, regtype:$Rm))]>,7600 Sched<[!if(!eq(regtype, V128), WriteVq, WriteVd)]> {7601 bits<5> Rd;7602 bits<5> Rn;7603 bits<5> Rm;7604 let Inst{31} = 0;7605 let Inst{30} = size{0};7606 let Inst{29-24} = 0b001110;7607 let Inst{23-22} = size{2-1};7608 let Inst{21} = 0;7609 let Inst{20-16} = Rm;7610 let Inst{15} = 0;7611 let Inst{14-12} = opc;7612 let Inst{11-10} = 0b10;7613 let Inst{9-5} = Rn;7614 let Inst{4-0} = Rd;7615}7616 7617multiclass SIMDZipVector<bits<3>opc, string asm,7618 SDNode OpNode> {7619 def v8i8 : BaseSIMDZipVector<0b000, opc, V64,7620 asm, ".8b", OpNode, v8i8>;7621 def v16i8 : BaseSIMDZipVector<0b001, opc, V128,7622 asm, ".16b", OpNode, v16i8>;7623 def v4i16 : BaseSIMDZipVector<0b010, opc, V64,7624 asm, ".4h", OpNode, v4i16>;7625 def v8i16 : BaseSIMDZipVector<0b011, opc, V128,7626 asm, ".8h", OpNode, v8i16>;7627 def v2i32 : BaseSIMDZipVector<0b100, opc, V64,7628 asm, ".2s", OpNode, v2i32>;7629 def v4i32 : BaseSIMDZipVector<0b101, opc, V128,7630 asm, ".4s", OpNode, v4i32>;7631 def v2i64 : BaseSIMDZipVector<0b111, opc, V128,7632 asm, ".2d", OpNode, v2i64>;7633 7634 def : Pat<(v4f16 (OpNode V64:$Rn, V64:$Rm)),7635 (!cast<Instruction>(NAME#"v4i16") V64:$Rn, V64:$Rm)>;7636 def : Pat<(v4bf16 (OpNode V64:$Rn, V64:$Rm)),7637 (!cast<Instruction>(NAME#"v4i16") V64:$Rn, V64:$Rm)>;7638 def : Pat<(v8f16 (OpNode V128:$Rn, V128:$Rm)),7639 (!cast<Instruction>(NAME#"v8i16") V128:$Rn, V128:$Rm)>;7640 def : Pat<(v8bf16 (OpNode V128:$Rn, V128:$Rm)),7641 (!cast<Instruction>(NAME#"v8i16") V128:$Rn, V128:$Rm)>;7642 def : Pat<(v2f32 (OpNode V64:$Rn, V64:$Rm)),7643 (!cast<Instruction>(NAME#"v2i32") V64:$Rn, V64:$Rm)>;7644 def : Pat<(v4f32 (OpNode V128:$Rn, V128:$Rm)),7645 (!cast<Instruction>(NAME#"v4i32") V128:$Rn, V128:$Rm)>;7646 def : Pat<(v2f64 (OpNode V128:$Rn, V128:$Rm)),7647 (!cast<Instruction>(NAME#"v2i64") V128:$Rn, V128:$Rm)>;7648}7649 7650//----------------------------------------------------------------------------7651// AdvSIMD three register scalar instructions7652//----------------------------------------------------------------------------7653 7654let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in7655class BaseSIMDThreeScalar<bit U, bits<3> size, bits<5> opcode,7656 RegisterClass regtype, string asm,7657 list<dag> pattern>7658 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm), asm,7659 "\t$Rd, $Rn, $Rm", "", pattern>,7660 Sched<[WriteVd]> {7661 bits<5> Rd;7662 bits<5> Rn;7663 bits<5> Rm;7664 let Inst{31-30} = 0b01;7665 let Inst{29} = U;7666 let Inst{28-24} = 0b11110;7667 let Inst{23-21} = size;7668 let Inst{20-16} = Rm;7669 let Inst{15-11} = opcode;7670 let Inst{10} = 1;7671 let Inst{9-5} = Rn;7672 let Inst{4-0} = Rd;7673}7674 7675let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in7676class BaseSIMDThreeScalarTied<bit U, bits<2> size, bit R, bits<5> opcode,7677 dag oops, dag iops, string asm,7678 list<dag> pattern>7679 : I<oops, iops, asm, "\t$Rd, $Rn, $Rm", "$Rd = $dst", pattern>,7680 Sched<[WriteVd]> {7681 bits<5> Rd;7682 bits<5> Rn;7683 bits<5> Rm;7684 let Inst{31-30} = 0b01;7685 let Inst{29} = U;7686 let Inst{28-24} = 0b11110;7687 let Inst{23-22} = size;7688 let Inst{21} = R;7689 let Inst{20-16} = Rm;7690 let Inst{15-11} = opcode;7691 let Inst{10} = 1;7692 let Inst{9-5} = Rn;7693 let Inst{4-0} = Rd;7694}7695 7696multiclass SIMDThreeScalarD<bit U, bits<5> opc, string asm,7697 SDPatternOperator OpNode> {7698 def v1i64 : BaseSIMDThreeScalar<U, 0b111, opc, FPR64, asm,7699 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>;7700}7701 7702multiclass SIMDThreeScalarBHSD<bit U, bits<5> opc, string asm,7703 SDPatternOperator OpNode, SDPatternOperator SatOp> {7704 def v1i64 : BaseSIMDThreeScalar<U, 0b111, opc, FPR64, asm,7705 [(set (v1i64 FPR64:$Rd), (SatOp (v1i64 FPR64:$Rn), (v1i64 FPR64:$Rm)))]>;7706 def v1i32 : BaseSIMDThreeScalar<U, 0b101, opc, FPR32, asm, []>;7707 def v1i16 : BaseSIMDThreeScalar<U, 0b011, opc, FPR16, asm, []>;7708 def v1i8 : BaseSIMDThreeScalar<U, 0b001, opc, FPR8 , asm, []>;7709 7710 def : Pat<(i64 (OpNode (i64 FPR64:$Rn), (i64 FPR64:$Rm))),7711 (!cast<Instruction>(NAME#"v1i64") FPR64:$Rn, FPR64:$Rm)>;7712 def : Pat<(i32 (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm))),7713 (!cast<Instruction>(NAME#"v1i32") FPR32:$Rn, FPR32:$Rm)>;7714}7715 7716multiclass SIMDThreeScalarHS<bit U, bits<5> opc, string asm,7717 SDPatternOperator OpNode> {7718 def v1i32 : BaseSIMDThreeScalar<U, 0b101, opc, FPR32, asm,7719 [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>;7720 def v1i16 : BaseSIMDThreeScalar<U, 0b011, opc, FPR16, asm, []>;7721}7722 7723multiclass SIMDThreeScalarHSTied<bit U, bit R, bits<5> opc, string asm> {7724 def v1i32: BaseSIMDThreeScalarTied<U, 0b10, R, opc, (outs FPR32:$dst),7725 (ins FPR32:$Rd, FPR32:$Rn, FPR32:$Rm),7726 asm, []>;7727 def v1i16: BaseSIMDThreeScalarTied<U, 0b01, R, opc, (outs FPR16:$dst),7728 (ins FPR16:$Rd, FPR16:$Rn, FPR16:$Rm),7729 asm, []>;7730}7731 7732multiclass SIMDFPThreeScalar<bit U, bit S, bits<3> opc, string asm,7733 SDPatternOperator OpNode = null_frag,7734 Predicate pred = HasNEON> {7735 let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in {7736 let Predicates = [pred] in {7737 def NAME#64 : BaseSIMDThreeScalar<U, {S,0b11}, {0b11,opc}, FPR64, asm,7738 [(set (f64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>;7739 def NAME#32 : BaseSIMDThreeScalar<U, {S,0b01}, {0b11,opc}, FPR32, asm,7740 [(set FPR32:$Rd, (OpNode FPR32:$Rn, FPR32:$Rm))]>;7741 }7742 let Predicates = [pred, HasFullFP16] in {7743 def NAME#16 : BaseSIMDThreeScalar<U, {S,0b10}, {0b00,opc}, FPR16, asm,7744 [(set (f16 FPR16:$Rd), (OpNode (f16 FPR16:$Rn), (f16 FPR16:$Rm)))]>;7745 }7746 }7747 7748 def : Pat<(v1f64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))),7749 (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>;7750}7751 7752multiclass SIMDThreeScalarFPCmp<bit U, bit S, bits<3> opc, string asm,7753 SDPatternOperator OpNode = null_frag> {7754 let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in {7755 def NAME#64 : BaseSIMDThreeScalar<U, {S,0b11}, {0b11,opc}, FPR64, asm,7756 [(set (i64 FPR64:$Rd), (OpNode (f64 FPR64:$Rn), (f64 FPR64:$Rm)))]>;7757 def NAME#32 : BaseSIMDThreeScalar<U, {S,0b01}, {0b11,opc}, FPR32, asm,7758 [(set (i32 FPR32:$Rd), (OpNode (f32 FPR32:$Rn), (f32 FPR32:$Rm)))]>;7759 let Predicates = [HasNEON, HasFullFP16] in {7760 def NAME#16 : BaseSIMDThreeScalar<U, {S,0b10}, {0b00,opc}, FPR16, asm,7761 []>;7762 } // Predicates = [HasNEON, HasFullFP16]7763 }7764 7765 def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn), (v1f64 FPR64:$Rm))),7766 (!cast<Instruction>(NAME # "64") FPR64:$Rn, FPR64:$Rm)>;7767}7768 7769class BaseSIMDThreeScalarMixed<bit U, bits<2> size, bits<5> opcode,7770 dag oops, dag iops, string asm, string cstr, list<dag> pat>7771 : I<oops, iops, asm,7772 "\t$Rd, $Rn, $Rm", cstr, pat>,7773 Sched<[WriteVd]> {7774 bits<5> Rd;7775 bits<5> Rn;7776 bits<5> Rm;7777 let Inst{31-30} = 0b01;7778 let Inst{29} = U;7779 let Inst{28-24} = 0b11110;7780 let Inst{23-22} = size;7781 let Inst{21} = 1;7782 let Inst{20-16} = Rm;7783 let Inst{15-11} = opcode;7784 let Inst{10} = 0;7785 let Inst{9-5} = Rn;7786 let Inst{4-0} = Rd;7787}7788 7789let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in7790multiclass SIMDThreeScalarMixedHS<bit U, bits<5> opc, string asm,7791 SDPatternOperator OpNode = null_frag> {7792 def i16 : BaseSIMDThreeScalarMixed<U, 0b01, opc,7793 (outs FPR32:$Rd),7794 (ins FPR16:$Rn, FPR16:$Rm), asm, "", []>;7795 def i32 : BaseSIMDThreeScalarMixed<U, 0b10, opc,7796 (outs FPR64:$Rd),7797 (ins FPR32:$Rn, FPR32:$Rm), asm, "",7798 [(set (i64 FPR64:$Rd), (OpNode (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>;7799}7800 7801let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in7802multiclass SIMDThreeScalarMixedTiedHS<bit U, bits<5> opc, string asm,7803 SDPatternOperator OpNode = null_frag> {7804 def i16 : BaseSIMDThreeScalarMixed<U, 0b01, opc,7805 (outs FPR32:$dst),7806 (ins FPR32:$Rd, FPR16:$Rn, FPR16:$Rm),7807 asm, "$Rd = $dst", []>;7808 def i32 : BaseSIMDThreeScalarMixed<U, 0b10, opc,7809 (outs FPR64:$dst),7810 (ins FPR64:$Rd, FPR32:$Rn, FPR32:$Rm),7811 asm, "$Rd = $dst",7812 [(set (i64 FPR64:$dst),7813 (OpNode (i64 FPR64:$Rd), (i32 FPR32:$Rn), (i32 FPR32:$Rm)))]>;7814}7815 7816//----------------------------------------------------------------------------7817// AdvSIMD two register scalar instructions7818//----------------------------------------------------------------------------7819 7820let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in7821class BaseSIMDTwoScalar<bit U, bits<2> size, bits<2> size2, bits<5> opcode,7822 RegisterClass regtype, RegisterClass regtype2,7823 string asm, list<dag> pat>7824 : I<(outs regtype:$Rd), (ins regtype2:$Rn), asm,7825 "\t$Rd, $Rn", "", pat>,7826 Sched<[WriteVd]> {7827 bits<5> Rd;7828 bits<5> Rn;7829 let Inst{31-30} = 0b01;7830 let Inst{29} = U;7831 let Inst{28-24} = 0b11110;7832 let Inst{23-22} = size;7833 let Inst{21} = 0b1;7834 let Inst{20-19} = size2;7835 let Inst{18-17} = 0b00;7836 let Inst{16-12} = opcode;7837 let Inst{11-10} = 0b10;7838 let Inst{9-5} = Rn;7839 let Inst{4-0} = Rd;7840}7841 7842let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in7843class BaseSIMDTwoScalarTied<bit U, bits<2> size, bits<5> opcode,7844 RegisterClass regtype, RegisterClass regtype2,7845 string asm, list<dag> pat>7846 : I<(outs regtype:$dst), (ins regtype:$Rd, regtype2:$Rn), asm,7847 "\t$Rd, $Rn", "$Rd = $dst", pat>,7848 Sched<[WriteVd]> {7849 bits<5> Rd;7850 bits<5> Rn;7851 let Inst{31-30} = 0b01;7852 let Inst{29} = U;7853 let Inst{28-24} = 0b11110;7854 let Inst{23-22} = size;7855 let Inst{21-17} = 0b10000;7856 let Inst{16-12} = opcode;7857 let Inst{11-10} = 0b10;7858 let Inst{9-5} = Rn;7859 let Inst{4-0} = Rd;7860}7861 7862 7863let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in7864class BaseSIMDCmpTwoScalar<bit U, bits<2> size, bits<2> size2, bits<5> opcode,7865 RegisterClass regtype, string asm, string zero>7866 : I<(outs regtype:$Rd), (ins regtype:$Rn), asm,7867 "\t$Rd, $Rn, #" # zero, "", []>,7868 Sched<[WriteVd]> {7869 bits<5> Rd;7870 bits<5> Rn;7871 let Inst{31-30} = 0b01;7872 let Inst{29} = U;7873 let Inst{28-24} = 0b11110;7874 let Inst{23-22} = size;7875 let Inst{21} = 0b1;7876 let Inst{20-19} = size2;7877 let Inst{18-17} = 0b00;7878 let Inst{16-12} = opcode;7879 let Inst{11-10} = 0b10;7880 let Inst{9-5} = Rn;7881 let Inst{4-0} = Rd;7882}7883 7884let mayRaiseFPException = 1, Uses = [FPCR] in7885class SIMDInexactCvtTwoScalar<bits<5> opcode, string asm>7886 : I<(outs FPR32:$Rd), (ins FPR64:$Rn), asm, "\t$Rd, $Rn", "",7887 [(set (f32 FPR32:$Rd), (AArch64fcvtxnsdr (f64 FPR64:$Rn)))]>,7888 Sched<[WriteVd]> {7889 bits<5> Rd;7890 bits<5> Rn;7891 let Inst{31-17} = 0b011111100110000;7892 let Inst{16-12} = opcode;7893 let Inst{11-10} = 0b10;7894 let Inst{9-5} = Rn;7895 let Inst{4-0} = Rd;7896}7897 7898multiclass SIMDCmpTwoScalarD<bit U, bits<5> opc, string asm,7899 SDPatternOperator OpNode> {7900 def v1i64rz : BaseSIMDCmpTwoScalar<U, 0b11, 0b00, opc, FPR64, asm, "0">;7901 7902 def : Pat<(v1i64 (OpNode v1i64:$Rn)),7903 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>;7904}7905 7906multiclass SIMDFPCmpTwoScalar<bit U, bit S, bits<5> opc, string asm,7907 SDPatternOperator OpNode> {7908 let mayRaiseFPException = 1, Uses = [FPCR] in {7909 def v1i64rz : BaseSIMDCmpTwoScalar<U, {S,1}, 0b00, opc, FPR64, asm, "0.0">;7910 def v1i32rz : BaseSIMDCmpTwoScalar<U, {S,0}, 0b00, opc, FPR32, asm, "0.0">;7911 let Predicates = [HasNEON, HasFullFP16] in {7912 def v1i16rz : BaseSIMDCmpTwoScalar<U, {S,1}, 0b11, opc, FPR16, asm, "0.0">;7913 }7914 }7915 7916 def : InstAlias<asm # "\t$Rd, $Rn, #0",7917 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rd, FPR64:$Rn), 0>;7918 def : InstAlias<asm # "\t$Rd, $Rn, #0",7919 (!cast<Instruction>(NAME # v1i32rz) FPR32:$Rd, FPR32:$Rn), 0>;7920 let Predicates = [HasNEON, HasFullFP16] in {7921 def : InstAlias<asm # "\t$Rd, $Rn, #0",7922 (!cast<Instruction>(NAME # v1i16rz) FPR16:$Rd, FPR16:$Rn), 0>;7923 }7924 7925 def : Pat<(v1i64 (OpNode (v1f64 FPR64:$Rn))),7926 (!cast<Instruction>(NAME # v1i64rz) FPR64:$Rn)>;7927}7928 7929multiclass SIMDTwoScalarD<bit U, bits<5> opc, string asm,7930 SDPatternOperator OpNode = null_frag,7931 list<Predicate> preds = []> {7932 def v1i64 : BaseSIMDTwoScalar<U, 0b11, 0b00, opc, FPR64, FPR64, asm,7933 [(set (v1i64 FPR64:$Rd), (OpNode (v1i64 FPR64:$Rn)))]>;7934 7935 let Predicates = preds in {7936 def : Pat<(i64 (OpNode (i64 FPR64:$Rn))),7937 (!cast<Instruction>(NAME # "v1i64") FPR64:$Rn)>;7938 }7939}7940 7941let mayRaiseFPException = 1, Uses = [FPCR], FastISelShouldIgnore = 1 in7942multiclass SIMDFPTwoScalar<bit U, bit S, bits<5> opc, string asm,7943 SDPatternOperator OpN = null_frag> {7944 let Predicates = [HasNEONandIsStreamingSafe] in {7945 def v1i64 : BaseSIMDTwoScalar<U, {S,1}, 0b00, opc, FPR64, FPR64, asm,7946 [(set (i64 FPR64:$Rd), (OpN (f64 FPR64:$Rn)))]>;7947 def v1i32 : BaseSIMDTwoScalar<U, {S,0}, 0b00, opc, FPR32, FPR32, asm,7948 [(set FPR32:$Rd, (i32 (OpN (f32 FPR32:$Rn))))]>;7949 }7950 let Predicates = [HasNEONandIsStreamingSafe, HasFullFP16] in {7951 def v1f16 : BaseSIMDTwoScalar<U, {S,1}, 0b11, opc, FPR16, FPR16, asm,7952 [(set FPR16:$Rd, (i16 (OpN (f16 FPR16:$Rn))))]>;7953 }7954}7955 7956let mayRaiseFPException = 1, Uses = [FPCR] in7957multiclass SIMDFPTwoScalarCVT<bit U, bit S, bits<5> opc, string asm,7958 SDPatternOperator OpNode> {7959 let Predicates = [HasNEONandIsStreamingSafe] in {7960 def v1i64 : BaseSIMDTwoScalar<U, {S,1}, 0b00, opc, FPR64, FPR64, asm,7961 [(set FPR64:$Rd, (OpNode (f64 FPR64:$Rn)))]>;7962 def v1i32 : BaseSIMDTwoScalar<U, {S,0}, 0b00, opc, FPR32, FPR32, asm,7963 [(set FPR32:$Rd, (OpNode (f32 FPR32:$Rn)))]>;7964 }7965 let Predicates = [HasNEONandIsStreamingSafe, HasFullFP16] in {7966 def v1i16 : BaseSIMDTwoScalar<U, {S,1}, 0b11, opc, FPR16, FPR16, asm,7967 [(set (f16 FPR16:$Rd), (OpNode (f16 FPR16:$Rn)))]>;7968 }7969}7970 7971multiclass SIMDTwoScalarBHSD<bit U, bits<5> opc, string asm,7972 SDPatternOperator OpNode = null_frag> {7973 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {7974 def v1i64 : BaseSIMDTwoScalar<U, 0b11, 0b00, opc, FPR64, FPR64, asm,7975 [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn)))]>;7976 def v1i32 : BaseSIMDTwoScalar<U, 0b10, 0b00, opc, FPR32, FPR32, asm,7977 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>;7978 def v1i16 : BaseSIMDTwoScalar<U, 0b01, 0b00, opc, FPR16, FPR16, asm, []>;7979 def v1i8 : BaseSIMDTwoScalar<U, 0b00, 0b00, opc, FPR8 , FPR8 , asm, []>;7980 }7981 7982 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn))),7983 (!cast<Instruction>(NAME # v1i64) FPR64:$Rn)>;7984}7985 7986multiclass SIMDTwoScalarBHSDTied<bit U, bits<5> opc, string asm,7987 Intrinsic OpNode> {7988 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {7989 def v1i64 : BaseSIMDTwoScalarTied<U, 0b11, opc, FPR64, FPR64, asm,7990 [(set (i64 FPR64:$dst), (OpNode (i64 FPR64:$Rd), (i64 FPR64:$Rn)))]>;7991 def v1i32 : BaseSIMDTwoScalarTied<U, 0b10, opc, FPR32, FPR32, asm,7992 [(set (i32 FPR32:$dst), (OpNode (i32 FPR32:$Rd), (i32 FPR32:$Rn)))]>;7993 def v1i16 : BaseSIMDTwoScalarTied<U, 0b01, opc, FPR16, FPR16, asm, []>;7994 def v1i8 : BaseSIMDTwoScalarTied<U, 0b00, opc, FPR8 , FPR8 , asm, []>;7995 }7996 7997 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn))),7998 (!cast<Instruction>(NAME # v1i64) FPR64:$Rd, FPR64:$Rn)>;7999}8000 8001 8002 8003let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in8004multiclass SIMDTwoScalarMixedBHS<bit U, bits<5> opc, string asm,8005 SDPatternOperator OpNode = null_frag> {8006 def v1i32 : BaseSIMDTwoScalar<U, 0b10, 0b00, opc, FPR32, FPR64, asm,8007 [(set (f32 FPR32:$Rd), (OpNode (f64 FPR64:$Rn)))]>;8008 def v1i16 : BaseSIMDTwoScalar<U, 0b01, 0b00, opc, FPR16, FPR32, asm, []>;8009 def v1i8 : BaseSIMDTwoScalar<U, 0b00, 0b00, opc, FPR8 , FPR16, asm, []>;8010}8011 8012//----------------------------------------------------------------------------8013// AdvSIMD scalar pairwise instructions8014//----------------------------------------------------------------------------8015 8016let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in8017class BaseSIMDPairwiseScalar<bit U, bits<2> size, bits<5> opcode,8018 RegisterOperand regtype, RegisterOperand vectype,8019 string asm, string kind>8020 : I<(outs regtype:$Rd), (ins vectype:$Rn), asm,8021 "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", []>,8022 Sched<[WriteVd]> {8023 bits<5> Rd;8024 bits<5> Rn;8025 let Inst{31-30} = 0b01;8026 let Inst{29} = U;8027 let Inst{28-24} = 0b11110;8028 let Inst{23-22} = size;8029 let Inst{21-17} = 0b11000;8030 let Inst{16-12} = opcode;8031 let Inst{11-10} = 0b10;8032 let Inst{9-5} = Rn;8033 let Inst{4-0} = Rd;8034}8035 8036multiclass SIMDPairwiseScalarD<bit U, bits<5> opc, string asm> {8037 def v2i64p : BaseSIMDPairwiseScalar<U, 0b11, opc, FPR64Op, V128,8038 asm, ".2d">;8039}8040 8041let mayRaiseFPException = 1, Uses = [FPCR] in8042multiclass SIMDFPPairwiseScalar<bit S, bits<5> opc, string asm> {8043 let Predicates = [HasNEON, HasFullFP16] in {8044 def v2i16p : BaseSIMDPairwiseScalar<0, {S,0}, opc, FPR16Op, V64,8045 asm, ".2h">;8046 }8047 def v2i32p : BaseSIMDPairwiseScalar<1, {S,0}, opc, FPR32Op, V64,8048 asm, ".2s">;8049 def v2i64p : BaseSIMDPairwiseScalar<1, {S,1}, opc, FPR64Op, V128,8050 asm, ".2d">;8051}8052 8053//----------------------------------------------------------------------------8054// AdvSIMD across lanes instructions8055//----------------------------------------------------------------------------8056 8057let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in8058class BaseSIMDAcrossLanes<bit Q, bit U, bits<2> size, bits<5> opcode,8059 RegisterClass regtype, RegisterOperand vectype,8060 string asm, string kind, list<dag> pattern>8061 : I<(outs regtype:$Rd), (ins vectype:$Rn), asm,8062 "{\t$Rd, $Rn" # kind # "|" # kind # "\t$Rd, $Rn}", "", pattern>,8063 Sched<[!if(Q, WriteVq, WriteVd)]> {8064 bits<5> Rd;8065 bits<5> Rn;8066 let Inst{31} = 0;8067 let Inst{30} = Q;8068 let Inst{29} = U;8069 let Inst{28-24} = 0b01110;8070 let Inst{23-22} = size;8071 let Inst{21-17} = 0b11000;8072 let Inst{16-12} = opcode;8073 let Inst{11-10} = 0b10;8074 let Inst{9-5} = Rn;8075 let Inst{4-0} = Rd;8076}8077 8078multiclass SIMDAcrossLanesBHS<bit U, bits<5> opcode,8079 string asm> {8080 def v8i8v : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR8, V64,8081 asm, ".8b", []>;8082 def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR8, V128,8083 asm, ".16b", []>;8084 def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR16, V64,8085 asm, ".4h", []>;8086 def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR16, V128,8087 asm, ".8h", []>;8088 def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR32, V128,8089 asm, ".4s", []>;8090}8091 8092multiclass SIMDAcrossLanesHSD<bit U, bits<5> opcode, string asm> {8093 def v8i8v : BaseSIMDAcrossLanes<0, U, 0b00, opcode, FPR16, V64,8094 asm, ".8b", []>;8095 def v16i8v : BaseSIMDAcrossLanes<1, U, 0b00, opcode, FPR16, V128,8096 asm, ".16b", []>;8097 def v4i16v : BaseSIMDAcrossLanes<0, U, 0b01, opcode, FPR32, V64,8098 asm, ".4h", []>;8099 def v8i16v : BaseSIMDAcrossLanes<1, U, 0b01, opcode, FPR32, V128,8100 asm, ".8h", []>;8101 def v4i32v : BaseSIMDAcrossLanes<1, U, 0b10, opcode, FPR64, V128,8102 asm, ".4s", []>;8103}8104 8105let mayRaiseFPException = 1, Uses = [FPCR] in8106multiclass SIMDFPAcrossLanes<bits<5> opcode, bit sz1, string asm,8107 SDPatternOperator intOp> {8108 let Predicates = [HasNEON, HasFullFP16] in {8109 def v4i16v : BaseSIMDAcrossLanes<0, 0, {sz1, 0}, opcode, FPR16, V64,8110 asm, ".4h",8111 [(set (f16 FPR16:$Rd), (intOp (v4f16 V64:$Rn)))]>;8112 def v8i16v : BaseSIMDAcrossLanes<1, 0, {sz1, 0}, opcode, FPR16, V128,8113 asm, ".8h",8114 [(set (f16 FPR16:$Rd), (intOp (v8f16 V128:$Rn)))]>;8115 } // Predicates = [HasNEON, HasFullFP16]8116 def v4i32v : BaseSIMDAcrossLanes<1, 1, {sz1, 0}, opcode, FPR32, V128,8117 asm, ".4s",8118 [(set FPR32:$Rd, (intOp (v4f32 V128:$Rn)))]>;8119}8120 8121//----------------------------------------------------------------------------8122// AdvSIMD INS/DUP instructions8123//----------------------------------------------------------------------------8124 8125// FIXME: There has got to be a better way to factor these. ugh.8126 8127class BaseSIMDInsDup<bit Q, bit op, dag outs, dag ins, string asm,8128 string operands, string constraints, list<dag> pattern>8129 : I<outs, ins, asm, operands, constraints, pattern>,8130 Sched<[!if(Q, WriteVq, WriteVd)]> {8131 bits<5> Rd;8132 bits<5> Rn;8133 let Inst{31} = 0;8134 let Inst{30} = Q;8135 let Inst{29} = op;8136 let Inst{28-21} = 0b01110000;8137 let Inst{15} = 0;8138 let Inst{10} = 1;8139 let Inst{9-5} = Rn;8140 let Inst{4-0} = Rd;8141}8142 8143class SIMDDupFromMain<bit Q, bits<5> imm5, string size, ValueType vectype,8144 RegisterOperand vecreg, RegisterClass regtype>8145 : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins regtype:$Rn), "dup",8146 "{\t$Rd" # size # ", $Rn" #8147 "|" # size # "\t$Rd, $Rn}", "",8148 [(set (vectype vecreg:$Rd), (AArch64dup regtype:$Rn))]> {8149 let Inst{20-16} = imm5;8150 let Inst{14-11} = 0b0001;8151}8152 8153class SIMDDupFromElement<bit Q, string dstkind, string srckind,8154 ValueType vectype, ValueType insreg,8155 RegisterOperand vecreg, Operand idxtype,8156 SDNode OpNode>8157 : BaseSIMDInsDup<Q, 0, (outs vecreg:$Rd), (ins V128:$Rn, idxtype:$idx), "dup",8158 "{\t$Rd" # dstkind # ", $Rn" # srckind # "$idx" #8159 "|" # dstkind # "\t$Rd, $Rn$idx}", "",8160 [(set (vectype vecreg:$Rd),8161 (OpNode (insreg V128:$Rn), idxtype:$idx))]> {8162 let Inst{14-11} = 0b0000;8163}8164 8165class SIMDDup64FromElement8166 : SIMDDupFromElement<1, ".2d", ".d", v2i64, v2i64, V128,8167 VectorIndexD, AArch64duplane64> {8168 bits<1> idx;8169 let Inst{20} = idx;8170 let Inst{19-16} = 0b1000;8171}8172 8173class SIMDDup32FromElement<bit Q, string size, ValueType vectype,8174 RegisterOperand vecreg>8175 : SIMDDupFromElement<Q, size, ".s", vectype, v4i32, vecreg,8176 VectorIndexS, AArch64duplane32> {8177 bits<2> idx;8178 let Inst{20-19} = idx;8179 let Inst{18-16} = 0b100;8180}8181 8182class SIMDDup16FromElement<bit Q, string size, ValueType vectype,8183 RegisterOperand vecreg>8184 : SIMDDupFromElement<Q, size, ".h", vectype, v8i16, vecreg,8185 VectorIndexH, AArch64duplane16> {8186 bits<3> idx;8187 let Inst{20-18} = idx;8188 let Inst{17-16} = 0b10;8189}8190 8191class SIMDDup8FromElement<bit Q, string size, ValueType vectype,8192 RegisterOperand vecreg>8193 : SIMDDupFromElement<Q, size, ".b", vectype, v16i8, vecreg,8194 VectorIndexB, AArch64duplane8> {8195 bits<4> idx;8196 let Inst{20-17} = idx;8197 let Inst{16} = 1;8198}8199 8200class BaseSIMDMov<bit Q, string size, bits<4> imm4, RegisterClass regtype,8201 Operand idxtype, string asm, list<dag> pattern>8202 : BaseSIMDInsDup<Q, 0, (outs regtype:$Rd), (ins V128:$Rn, idxtype:$idx), asm,8203 "{\t$Rd, $Rn" # size # "$idx" #8204 "|" # size # "\t$Rd, $Rn$idx}", "", pattern> {8205 let Inst{14-11} = imm4;8206}8207 8208class SIMDSMov<bit Q, string size, RegisterClass regtype,8209 Operand idxtype>8210 : BaseSIMDMov<Q, size, 0b0101, regtype, idxtype, "smov", []>;8211class SIMDUMov<bit Q, string size, ValueType vectype, RegisterClass regtype,8212 Operand idxtype>8213 : BaseSIMDMov<Q, size, 0b0111, regtype, idxtype, "umov",8214 [(set regtype:$Rd, (vector_extract (vectype V128:$Rn), idxtype:$idx))]>;8215 8216class SIMDMovAlias<string asm, string size, Instruction inst,8217 RegisterClass regtype, Operand idxtype>8218 : InstAlias<asm#"{\t$dst, $src"#size#"$idx" #8219 "|" # size # "\t$dst, $src$idx}",8220 (inst regtype:$dst, V128:$src, idxtype:$idx)>;8221 8222multiclass SMov {8223 // SMOV with vector index of 0 are legal in Scalable Matrix Extension (SME)8224 // streaming mode.8225 let Predicates = [HasNEONandIsStreamingSafe] in {8226 def vi8to32_idx0 : SIMDSMov<0, ".b", GPR32, VectorIndex0> {8227 bits<0> idx;8228 let Inst{20-16} = 0b00001;8229 }8230 def vi8to64_idx0 : SIMDSMov<1, ".b", GPR64, VectorIndex0> {8231 bits<0> idx;8232 let Inst{20-16} = 0b00001;8233 }8234 def vi16to32_idx0 : SIMDSMov<0, ".h", GPR32, VectorIndex0> {8235 bits<0> idx;8236 let Inst{20-16} = 0b00010;8237 }8238 def vi16to64_idx0 : SIMDSMov<1, ".h", GPR64, VectorIndex0> {8239 bits<0> idx;8240 let Inst{20-16} = 0b00010;8241 }8242 def vi32to64_idx0 : SIMDSMov<1, ".s", GPR64, VectorIndex0> {8243 bits<0> idx;8244 let Inst{20-16} = 0b00100;8245 }8246 }8247 def vi8to32 : SIMDSMov<0, ".b", GPR32, VectorIndexB> {8248 bits<4> idx;8249 let Inst{20-17} = idx;8250 let Inst{16} = 1;8251 }8252 def vi8to64 : SIMDSMov<1, ".b", GPR64, VectorIndexB> {8253 bits<4> idx;8254 let Inst{20-17} = idx;8255 let Inst{16} = 1;8256 }8257 def vi16to32 : SIMDSMov<0, ".h", GPR32, VectorIndexH> {8258 bits<3> idx;8259 let Inst{20-18} = idx;8260 let Inst{17-16} = 0b10;8261 }8262 def vi16to64 : SIMDSMov<1, ".h", GPR64, VectorIndexH> {8263 bits<3> idx;8264 let Inst{20-18} = idx;8265 let Inst{17-16} = 0b10;8266 }8267 def vi32to64 : SIMDSMov<1, ".s", GPR64, VectorIndexS> {8268 bits<2> idx;8269 let Inst{20-19} = idx;8270 let Inst{18-16} = 0b100;8271 }8272}8273 8274multiclass UMov {8275 // UMOV with vector index of 0 are legal in Scalable Matrix Extension (SME)8276 // streaming mode.8277 let Predicates = [HasNEONandIsStreamingSafe] in {8278 def vi8_idx0 : SIMDUMov<0, ".b", v16i8, GPR32, VectorIndex0> {8279 bits<0> idx;8280 let Inst{20-16} = 0b00001;8281 }8282 def vi16_idx0 : SIMDUMov<0, ".h", v8i16, GPR32, VectorIndex0> {8283 bits<0> idx;8284 let Inst{20-16} = 0b00010;8285 }8286 def vi32_idx0 : SIMDUMov<0, ".s", v4i32, GPR32, VectorIndex0> {8287 bits<0> idx;8288 let Inst{20-16} = 0b00100;8289 }8290 def vi64_idx0 : SIMDUMov<1, ".d", v2i64, GPR64, VectorIndex0> {8291 bits<0> idx;8292 let Inst{20-16} = 0b01000;8293 }8294 def : SIMDMovAlias<"mov", ".s",8295 !cast<Instruction>(NAME # vi32_idx0),8296 GPR32, VectorIndex0>;8297 def : SIMDMovAlias<"mov", ".d",8298 !cast<Instruction>(NAME # vi64_idx0),8299 GPR64, VectorIndex0>;8300 }8301 def vi8 : SIMDUMov<0, ".b", v16i8, GPR32, VectorIndexB> {8302 bits<4> idx;8303 let Inst{20-17} = idx;8304 let Inst{16} = 1;8305 }8306 def vi16 : SIMDUMov<0, ".h", v8i16, GPR32, VectorIndexH> {8307 bits<3> idx;8308 let Inst{20-18} = idx;8309 let Inst{17-16} = 0b10;8310 }8311 def vi32 : SIMDUMov<0, ".s", v4i32, GPR32, VectorIndexS> {8312 bits<2> idx;8313 let Inst{20-19} = idx;8314 let Inst{18-16} = 0b100;8315 }8316 def vi64 : SIMDUMov<1, ".d", v2i64, GPR64, VectorIndexD> {8317 bits<1> idx;8318 let Inst{20} = idx;8319 let Inst{19-16} = 0b1000;8320 }8321 def : SIMDMovAlias<"mov", ".s",8322 !cast<Instruction>(NAME#"vi32"),8323 GPR32, VectorIndexS>;8324 def : SIMDMovAlias<"mov", ".d",8325 !cast<Instruction>(NAME#"vi64"),8326 GPR64, VectorIndexD>;8327}8328 8329class SIMDInsFromMain<string size, ValueType vectype,8330 RegisterClass regtype, Operand idxtype>8331 : BaseSIMDInsDup<1, 0, (outs V128:$dst),8332 (ins V128:$Rd, idxtype:$idx, regtype:$Rn), "ins",8333 "{\t$Rd" # size # "$idx, $Rn" #8334 "|" # size # "\t$Rd$idx, $Rn}",8335 "$Rd = $dst",8336 [(set V128:$dst,8337 (vector_insert (vectype V128:$Rd), regtype:$Rn, (i64 idxtype:$idx)))]> {8338 let Inst{14-11} = 0b0011;8339}8340 8341class SIMDInsFromElement<string size, ValueType vectype,8342 ValueType elttype, Operand idxtype>8343 : BaseSIMDInsDup<1, 1, (outs V128:$dst),8344 (ins V128:$Rd, idxtype:$idx, V128:$Rn, idxtype:$idx2), "ins",8345 "{\t$Rd" # size # "$idx, $Rn" # size # "$idx2" #8346 "|" # size # "\t$Rd$idx, $Rn$idx2}",8347 "$Rd = $dst",8348 [(set V128:$dst,8349 (vector_insert8350 (vectype V128:$Rd),8351 (elttype (vector_extract (vectype V128:$Rn), (i64 idxtype:$idx2))),8352 (i64 idxtype:$idx)))]>;8353 8354class SIMDInsMainMovAlias<string size, Instruction inst,8355 RegisterClass regtype, Operand idxtype>8356 : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" #8357 "|" # size #"\t$dst$idx, $src}",8358 (inst V128:$dst, idxtype:$idx, regtype:$src)>;8359class SIMDInsElementMovAlias<string size, Instruction inst,8360 Operand idxtype>8361 : InstAlias<"mov" # "{\t$dst" # size # "$idx, $src" # size # "$idx2"8362 # "|" # size #"\t$dst$idx, $src$idx2}",8363 (inst V128:$dst, idxtype:$idx, V128:$src, idxtype:$idx2)>;8364 8365 8366multiclass SIMDIns {8367 def vi8gpr : SIMDInsFromMain<".b", v16i8, GPR32, VectorIndexB> {8368 bits<4> idx;8369 let Inst{20-17} = idx;8370 let Inst{16} = 1;8371 }8372 def vi16gpr : SIMDInsFromMain<".h", v8i16, GPR32, VectorIndexH> {8373 bits<3> idx;8374 let Inst{20-18} = idx;8375 let Inst{17-16} = 0b10;8376 }8377 def vi32gpr : SIMDInsFromMain<".s", v4i32, GPR32, VectorIndexS> {8378 bits<2> idx;8379 let Inst{20-19} = idx;8380 let Inst{18-16} = 0b100;8381 }8382 def vi64gpr : SIMDInsFromMain<".d", v2i64, GPR64, VectorIndexD> {8383 bits<1> idx;8384 let Inst{20} = idx;8385 let Inst{19-16} = 0b1000;8386 }8387 8388 def vi8lane : SIMDInsFromElement<".b", v16i8, i32, VectorIndexB> {8389 bits<4> idx;8390 bits<4> idx2;8391 let Inst{20-17} = idx;8392 let Inst{16} = 1;8393 let Inst{14-11} = idx2;8394 }8395 def vi16lane : SIMDInsFromElement<".h", v8i16, i32, VectorIndexH> {8396 bits<3> idx;8397 bits<3> idx2;8398 let Inst{20-18} = idx;8399 let Inst{17-16} = 0b10;8400 let Inst{14-12} = idx2;8401 let Inst{11} = {?};8402 }8403 def vi32lane : SIMDInsFromElement<".s", v4i32, i32, VectorIndexS> {8404 bits<2> idx;8405 bits<2> idx2;8406 let Inst{20-19} = idx;8407 let Inst{18-16} = 0b100;8408 let Inst{14-13} = idx2;8409 let Inst{12-11} = {?,?};8410 }8411 def vi64lane : SIMDInsFromElement<".d", v2i64, i64, VectorIndexD> {8412 bits<1> idx;8413 bits<1> idx2;8414 let Inst{20} = idx;8415 let Inst{19-16} = 0b1000;8416 let Inst{14} = idx2;8417 let Inst{13-11} = {?,?,?};8418 }8419 8420 // For all forms of the INS instruction, the "mov" mnemonic is the8421 // preferred alias. Why they didn't just call the instruction "mov" in8422 // the first place is a very good question indeed...8423 def : SIMDInsMainMovAlias<".b", !cast<Instruction>(NAME#"vi8gpr"),8424 GPR32, VectorIndexB>;8425 def : SIMDInsMainMovAlias<".h", !cast<Instruction>(NAME#"vi16gpr"),8426 GPR32, VectorIndexH>;8427 def : SIMDInsMainMovAlias<".s", !cast<Instruction>(NAME#"vi32gpr"),8428 GPR32, VectorIndexS>;8429 def : SIMDInsMainMovAlias<".d", !cast<Instruction>(NAME#"vi64gpr"),8430 GPR64, VectorIndexD>;8431 8432 def : SIMDInsElementMovAlias<".b", !cast<Instruction>(NAME#"vi8lane"),8433 VectorIndexB>;8434 def : SIMDInsElementMovAlias<".h", !cast<Instruction>(NAME#"vi16lane"),8435 VectorIndexH>;8436 def : SIMDInsElementMovAlias<".s", !cast<Instruction>(NAME#"vi32lane"),8437 VectorIndexS>;8438 def : SIMDInsElementMovAlias<".d", !cast<Instruction>(NAME#"vi64lane"),8439 VectorIndexD>;8440}8441 8442//----------------------------------------------------------------------------8443// AdvSIMD TBL/TBX8444//----------------------------------------------------------------------------8445 8446let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in8447class BaseSIMDTableLookup<bit Q, bits<2> len, bit op, RegisterOperand vectype,8448 RegisterOperand listtype, string asm, string kind>8449 : I<(outs vectype:$Vd), (ins listtype:$Vn, vectype:$Vm), asm,8450 "\t$Vd" # kind # ", $Vn, $Vm" # kind, "", []>,8451 Sched<[!if(Q, WriteVq, WriteVd)]> {8452 bits<5> Vd;8453 bits<5> Vn;8454 bits<5> Vm;8455 let Inst{31} = 0;8456 let Inst{30} = Q;8457 let Inst{29-21} = 0b001110000;8458 let Inst{20-16} = Vm;8459 let Inst{15} = 0;8460 let Inst{14-13} = len;8461 let Inst{12} = op;8462 let Inst{11-10} = 0b00;8463 let Inst{9-5} = Vn;8464 let Inst{4-0} = Vd;8465}8466 8467let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in8468class BaseSIMDTableLookupTied<bit Q, bits<2> len, bit op, RegisterOperand vectype,8469 RegisterOperand listtype, string asm, string kind>8470 : I<(outs vectype:$dst), (ins vectype:$Vd, listtype:$Vn, vectype:$Vm), asm,8471 "\t$Vd" # kind # ", $Vn, $Vm" # kind, "$Vd = $dst", []>,8472 Sched<[!if(Q, WriteVq, WriteVd)]> {8473 bits<5> Vd;8474 bits<5> Vn;8475 bits<5> Vm;8476 let Inst{31} = 0;8477 let Inst{30} = Q;8478 let Inst{29-21} = 0b001110000;8479 let Inst{20-16} = Vm;8480 let Inst{15} = 0;8481 let Inst{14-13} = len;8482 let Inst{12} = op;8483 let Inst{11-10} = 0b00;8484 let Inst{9-5} = Vn;8485 let Inst{4-0} = Vd;8486}8487 8488class SIMDTableLookupAlias<string asm, Instruction inst,8489 RegisterOperand vectype, RegisterOperand listtype>8490 : InstAlias<!strconcat(asm, "\t$dst, $lst, $index"),8491 (inst vectype:$dst, listtype:$lst, vectype:$index), 0>;8492 8493multiclass SIMDTableLookup<bit op, string asm> {8494 def v8i8One : BaseSIMDTableLookup<0, 0b00, op, V64, VecListOne16b,8495 asm, ".8b">;8496 def v8i8Two : BaseSIMDTableLookup<0, 0b01, op, V64, VecListTwo16b,8497 asm, ".8b">;8498 def v8i8Three : BaseSIMDTableLookup<0, 0b10, op, V64, VecListThree16b,8499 asm, ".8b">;8500 def v8i8Four : BaseSIMDTableLookup<0, 0b11, op, V64, VecListFour16b,8501 asm, ".8b">;8502 def v16i8One : BaseSIMDTableLookup<1, 0b00, op, V128, VecListOne16b,8503 asm, ".16b">;8504 def v16i8Two : BaseSIMDTableLookup<1, 0b01, op, V128, VecListTwo16b,8505 asm, ".16b">;8506 def v16i8Three: BaseSIMDTableLookup<1, 0b10, op, V128, VecListThree16b,8507 asm, ".16b">;8508 def v16i8Four : BaseSIMDTableLookup<1, 0b11, op, V128, VecListFour16b,8509 asm, ".16b">;8510 8511 def : SIMDTableLookupAlias<asm # ".8b",8512 !cast<Instruction>(NAME#"v8i8One"),8513 V64, VecListOneConsecutive128>;8514 def : SIMDTableLookupAlias<asm # ".8b",8515 !cast<Instruction>(NAME#"v8i8Two"),8516 V64, VecListTwoConsecutive128>;8517 def : SIMDTableLookupAlias<asm # ".8b",8518 !cast<Instruction>(NAME#"v8i8Three"),8519 V64, VecListThreeConsecutive128>;8520 def : SIMDTableLookupAlias<asm # ".8b",8521 !cast<Instruction>(NAME#"v8i8Four"),8522 V64, VecListFourConsecutive128>;8523 def : SIMDTableLookupAlias<asm # ".16b",8524 !cast<Instruction>(NAME#"v16i8One"),8525 V128, VecListOneConsecutive128>;8526 def : SIMDTableLookupAlias<asm # ".16b",8527 !cast<Instruction>(NAME#"v16i8Two"),8528 V128, VecListTwoConsecutive128>;8529 def : SIMDTableLookupAlias<asm # ".16b",8530 !cast<Instruction>(NAME#"v16i8Three"),8531 V128, VecListThreeConsecutive128>;8532 def : SIMDTableLookupAlias<asm # ".16b",8533 !cast<Instruction>(NAME#"v16i8Four"),8534 V128, VecListFourConsecutive128>;8535}8536 8537multiclass SIMDTableLookupTied<bit op, string asm> {8538 def v8i8One : BaseSIMDTableLookupTied<0, 0b00, op, V64, VecListOne16b,8539 asm, ".8b">;8540 def v8i8Two : BaseSIMDTableLookupTied<0, 0b01, op, V64, VecListTwo16b,8541 asm, ".8b">;8542 def v8i8Three : BaseSIMDTableLookupTied<0, 0b10, op, V64, VecListThree16b,8543 asm, ".8b">;8544 def v8i8Four : BaseSIMDTableLookupTied<0, 0b11, op, V64, VecListFour16b,8545 asm, ".8b">;8546 def v16i8One : BaseSIMDTableLookupTied<1, 0b00, op, V128, VecListOne16b,8547 asm, ".16b">;8548 def v16i8Two : BaseSIMDTableLookupTied<1, 0b01, op, V128, VecListTwo16b,8549 asm, ".16b">;8550 def v16i8Three: BaseSIMDTableLookupTied<1, 0b10, op, V128, VecListThree16b,8551 asm, ".16b">;8552 def v16i8Four : BaseSIMDTableLookupTied<1, 0b11, op, V128, VecListFour16b,8553 asm, ".16b">;8554 8555 def : SIMDTableLookupAlias<asm # ".8b",8556 !cast<Instruction>(NAME#"v8i8One"),8557 V64, VecListOneConsecutive128>;8558 def : SIMDTableLookupAlias<asm # ".8b",8559 !cast<Instruction>(NAME#"v8i8Two"),8560 V64, VecListTwoConsecutive128>;8561 def : SIMDTableLookupAlias<asm # ".8b",8562 !cast<Instruction>(NAME#"v8i8Three"),8563 V64, VecListThreeConsecutive128>;8564 def : SIMDTableLookupAlias<asm # ".8b",8565 !cast<Instruction>(NAME#"v8i8Four"),8566 V64, VecListFourConsecutive128>;8567 def : SIMDTableLookupAlias<asm # ".16b",8568 !cast<Instruction>(NAME#"v16i8One"),8569 V128, VecListOneConsecutive128>;8570 def : SIMDTableLookupAlias<asm # ".16b",8571 !cast<Instruction>(NAME#"v16i8Two"),8572 V128, VecListTwoConsecutive128>;8573 def : SIMDTableLookupAlias<asm # ".16b",8574 !cast<Instruction>(NAME#"v16i8Three"),8575 V128, VecListThreeConsecutive128>;8576 def : SIMDTableLookupAlias<asm # ".16b",8577 !cast<Instruction>(NAME#"v16i8Four"),8578 V128, VecListFourConsecutive128>;8579}8580 8581//----------------------------------------------------------------------------8582// AdvSIMD LUT8583//----------------------------------------------------------------------------8584let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in8585class BaseSIMDTableLookupIndexed<bit Q, bits<5> opc,8586 RegisterOperand listtype, Operand idx_type,8587 string asm, string kind>8588 : I<(outs V128:$Rd),8589 (ins listtype:$Rn, V128:$Rm, idx_type:$idx),8590 asm, "\t$Rd" # kind # ", $Rn, $Rm$idx", "", []>,8591 Sched<[]> {8592 bits<5> Rd;8593 bits<5> Rn;8594 bits<5> Rm;8595 let Inst{31} = 0;8596 let Inst{30} = Q;8597 let Inst{29-24} = 0b001110;8598 let Inst{23-22} = opc{4-3};8599 let Inst{21} = 0;8600 let Inst{20-16} = Rm;8601 let Inst{15} = 0;8602 let Inst{14-12} = opc{2-0};8603 let Inst{11-10} = 0b00;8604 let Inst{9-5} = Rn;8605 let Inst{4-0} = Rd;8606}8607 8608multiclass BaseSIMDTableLookupIndexed2<string asm> {8609 def _B : BaseSIMDTableLookupIndexed<0b1, {0b10,?,?,0b1}, VecListOne16b, VectorIndexS32b_timm, asm, ".16b"> {8610 bits<2> idx;8611 let Inst{14-13} = idx;8612 }8613 def _H : BaseSIMDTableLookupIndexed<0b1, {0b11,?,?,?}, VecListOne8h, VectorIndexH32b_timm, asm, ".8h" > {8614 bits<3> idx;8615 let Inst{14-12} = idx;8616 }8617}8618 8619multiclass BaseSIMDTableLookupIndexed4<string asm> {8620 def _B : BaseSIMDTableLookupIndexed<0b1, {0b01,?,0b10}, VecListOne16b, VectorIndexD32b_timm, asm, ".16b"> {8621 bit idx;8622 let Inst{14} = idx;8623 }8624 def _H : BaseSIMDTableLookupIndexed<0b1, {0b01,?,?,0b1}, VecListTwo8h, VectorIndexS32b_timm, asm, ".8h" > {8625 bits<2> idx;8626 let Inst{14-13} = idx;8627 }8628}8629 8630//----------------------------------------------------------------------------8631// AdvSIMD scalar DUP8632//----------------------------------------------------------------------------8633let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in8634class BaseSIMDScalarDUP<RegisterClass regtype, RegisterOperand vectype,8635 string asm, string kind, Operand idxtype>8636 : I<(outs regtype:$dst), (ins vectype:$src, idxtype:$idx), asm,8637 "{\t$dst, $src" # kind # "$idx" #8638 "|\t$dst, $src$idx}", "", []>,8639 Sched<[WriteVd]> {8640 bits<5> dst;8641 bits<5> src;8642 let Inst{31-21} = 0b01011110000;8643 let Inst{15-10} = 0b000001;8644 let Inst{9-5} = src;8645 let Inst{4-0} = dst;8646}8647 8648class SIMDScalarDUPAlias<string asm, string size, Instruction inst,8649 RegisterClass regtype, RegisterOperand vectype, Operand idxtype>8650 : InstAlias<asm # "{\t$dst, $src" # size # "$index"8651 # "|\t$dst, $src$index}",8652 (inst regtype:$dst, vectype:$src, idxtype:$index), 0>;8653 8654 8655multiclass SIMDScalarDUP<string asm> {8656 def i8 : BaseSIMDScalarDUP<FPR8, V128, asm, ".b", VectorIndexB> {8657 bits<4> idx;8658 let Inst{20-17} = idx;8659 let Inst{16} = 1;8660 }8661 def i16 : BaseSIMDScalarDUP<FPR16, V128, asm, ".h", VectorIndexH> {8662 bits<3> idx;8663 let Inst{20-18} = idx;8664 let Inst{17-16} = 0b10;8665 }8666 def i32 : BaseSIMDScalarDUP<FPR32, V128, asm, ".s", VectorIndexS> {8667 bits<2> idx;8668 let Inst{20-19} = idx;8669 let Inst{18-16} = 0b100;8670 }8671 def i64 : BaseSIMDScalarDUP<FPR64, V128, asm, ".d", VectorIndexD> {8672 bits<1> idx;8673 let Inst{20} = idx;8674 let Inst{19-16} = 0b1000;8675 }8676 8677 def : Pat<(v1i64 (scalar_to_vector (i64 (vector_extract (v2i64 V128:$src),8678 VectorIndexD:$idx)))),8679 (!cast<Instruction>(NAME # i64) V128:$src, VectorIndexD:$idx)>;8680 8681 // 'DUP' mnemonic aliases.8682 def : SIMDScalarDUPAlias<"dup", ".b",8683 !cast<Instruction>(NAME#"i8"),8684 FPR8, V128, VectorIndexB>;8685 def : SIMDScalarDUPAlias<"dup", ".h",8686 !cast<Instruction>(NAME#"i16"),8687 FPR16, V128, VectorIndexH>;8688 def : SIMDScalarDUPAlias<"dup", ".s",8689 !cast<Instruction>(NAME#"i32"),8690 FPR32, V128, VectorIndexS>;8691 def : SIMDScalarDUPAlias<"dup", ".d",8692 !cast<Instruction>(NAME#"i64"),8693 FPR64, V128, VectorIndexD>;8694}8695 8696//----------------------------------------------------------------------------8697// AdvSIMD modified immediate instructions8698//----------------------------------------------------------------------------8699 8700class BaseSIMDModifiedImm<bit Q, bit op, bit op2, dag oops, dag iops,8701 string asm, string op_string,8702 string cstr, list<dag> pattern>8703 : I<oops, iops, asm, op_string, cstr, pattern>,8704 Sched<[!if(Q, WriteVq, WriteVd)]> {8705 bits<5> Rd;8706 bits<8> imm8;8707 let Inst{31} = 0;8708 let Inst{30} = Q;8709 let Inst{29} = op;8710 let Inst{28-19} = 0b0111100000;8711 let Inst{18-16} = imm8{7-5};8712 let Inst{11} = op2;8713 let Inst{10} = 1;8714 let Inst{9-5} = imm8{4-0};8715 let Inst{4-0} = Rd;8716}8717 8718class BaseSIMDModifiedImmVector<bit Q, bit op, bit op2, RegisterOperand vectype,8719 Operand immtype, dag opt_shift_iop,8720 string opt_shift, string asm, string kind,8721 list<dag> pattern>8722 : BaseSIMDModifiedImm<Q, op, op2, (outs vectype:$Rd),8723 !con((ins immtype:$imm8), opt_shift_iop), asm,8724 "{\t$Rd" # kind # ", $imm8" # opt_shift #8725 "|" # kind # "\t$Rd, $imm8" # opt_shift # "}",8726 "", pattern> {8727 let DecoderMethod = "DecodeModImmInstruction";8728}8729 8730class BaseSIMDModifiedImmVectorTied<bit Q, bit op, RegisterOperand vectype,8731 Operand immtype, dag opt_shift_iop,8732 string opt_shift, string asm, string kind,8733 list<dag> pattern>8734 : BaseSIMDModifiedImm<Q, op, 0, (outs vectype:$dst),8735 !con((ins vectype:$Rd, immtype:$imm8), opt_shift_iop),8736 asm, "{\t$Rd" # kind # ", $imm8" # opt_shift #8737 "|" # kind # "\t$Rd, $imm8" # opt_shift # "}",8738 "$Rd = $dst", pattern> {8739 let DecoderMethod = "DecodeModImmTiedInstruction";8740}8741 8742class BaseSIMDModifiedImmVectorShift<bit Q, bit op, bits<2> b15_b12,8743 RegisterOperand vectype, string asm,8744 string kind, list<dag> pattern>8745 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255,8746 (ins logical_vec_shift:$shift),8747 "$shift", asm, kind, pattern> {8748 bits<2> shift;8749 let Inst{15} = b15_b12{1};8750 let Inst{14-13} = shift;8751 let Inst{12} = b15_b12{0};8752}8753 8754class BaseSIMDModifiedImmVectorShiftTied<bit Q, bit op, bits<2> b15_b12,8755 RegisterOperand vectype, string asm,8756 string kind, list<dag> pattern>8757 : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255,8758 (ins logical_vec_shift:$shift),8759 "$shift", asm, kind, pattern> {8760 bits<2> shift;8761 let Inst{15} = b15_b12{1};8762 let Inst{14-13} = shift;8763 let Inst{12} = b15_b12{0};8764}8765 8766 8767class BaseSIMDModifiedImmVectorShiftHalf<bit Q, bit op, bits<2> b15_b12,8768 RegisterOperand vectype, string asm,8769 string kind, list<dag> pattern>8770 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255,8771 (ins logical_vec_hw_shift:$shift),8772 "$shift", asm, kind, pattern> {8773 bits<2> shift;8774 let Inst{15} = b15_b12{1};8775 let Inst{14} = 0;8776 let Inst{13} = shift{0};8777 let Inst{12} = b15_b12{0};8778}8779 8780class BaseSIMDModifiedImmVectorShiftHalfTied<bit Q, bit op, bits<2> b15_b12,8781 RegisterOperand vectype, string asm,8782 string kind, list<dag> pattern>8783 : BaseSIMDModifiedImmVectorTied<Q, op, vectype, imm0_255,8784 (ins logical_vec_hw_shift:$shift),8785 "$shift", asm, kind, pattern> {8786 bits<2> shift;8787 let Inst{15} = b15_b12{1};8788 let Inst{14} = 0;8789 let Inst{13} = shift{0};8790 let Inst{12} = b15_b12{0};8791}8792 8793multiclass SIMDModifiedImmVectorShift<bit op, bits<2> hw_cmode, bits<2> w_cmode,8794 string asm> {8795 def v4i16 : BaseSIMDModifiedImmVectorShiftHalf<0, op, hw_cmode, V64,8796 asm, ".4h", []>;8797 def v8i16 : BaseSIMDModifiedImmVectorShiftHalf<1, op, hw_cmode, V128,8798 asm, ".8h", []>;8799 8800 def v2i32 : BaseSIMDModifiedImmVectorShift<0, op, w_cmode, V64,8801 asm, ".2s", []>;8802 def v4i32 : BaseSIMDModifiedImmVectorShift<1, op, w_cmode, V128,8803 asm, ".4s", []>;8804}8805 8806multiclass SIMDModifiedImmVectorShiftTied<bit op, bits<2> hw_cmode,8807 bits<2> w_cmode, string asm,8808 SDNode OpNode> {8809 def v4i16 : BaseSIMDModifiedImmVectorShiftHalfTied<0, op, hw_cmode, V64,8810 asm, ".4h",8811 [(set (v4i16 V64:$dst), (OpNode V64:$Rd,8812 imm0_255:$imm8,8813 (i32 imm:$shift)))]>;8814 def v8i16 : BaseSIMDModifiedImmVectorShiftHalfTied<1, op, hw_cmode, V128,8815 asm, ".8h",8816 [(set (v8i16 V128:$dst), (OpNode V128:$Rd,8817 imm0_255:$imm8,8818 (i32 imm:$shift)))]>;8819 8820 def v2i32 : BaseSIMDModifiedImmVectorShiftTied<0, op, w_cmode, V64,8821 asm, ".2s",8822 [(set (v2i32 V64:$dst), (OpNode V64:$Rd,8823 imm0_255:$imm8,8824 (i32 imm:$shift)))]>;8825 def v4i32 : BaseSIMDModifiedImmVectorShiftTied<1, op, w_cmode, V128,8826 asm, ".4s",8827 [(set (v4i32 V128:$dst), (OpNode V128:$Rd,8828 imm0_255:$imm8,8829 (i32 imm:$shift)))]>;8830}8831 8832class SIMDModifiedImmMoveMSL<bit Q, bit op, bits<4> cmode,8833 RegisterOperand vectype, string asm,8834 string kind, list<dag> pattern>8835 : BaseSIMDModifiedImmVector<Q, op, 0, vectype, imm0_255,8836 (ins move_vec_shift:$shift),8837 "$shift", asm, kind, pattern> {8838 bits<1> shift;8839 let Inst{15-13} = cmode{3-1};8840 let Inst{12} = shift;8841}8842 8843class SIMDModifiedImmVectorNoShift<bit Q, bit op, bit op2, bits<4> cmode,8844 RegisterOperand vectype,8845 Operand imm_type, string asm,8846 string kind, list<dag> pattern>8847 : BaseSIMDModifiedImmVector<Q, op, op2, vectype, imm_type, (ins), "",8848 asm, kind, pattern> {8849 let Inst{15-12} = cmode;8850}8851 8852class SIMDModifiedImmScalarNoShift<bit Q, bit op, bits<4> cmode, string asm,8853 list<dag> pattern>8854 : BaseSIMDModifiedImm<Q, op, 0, (outs FPR64:$Rd), (ins simdimmtype10:$imm8), asm,8855 "\t$Rd, $imm8", "", pattern> {8856 let Inst{15-12} = cmode;8857 let DecoderMethod = "DecodeModImmInstruction";8858}8859 8860//----------------------------------------------------------------------------8861// AdvSIMD indexed element8862//----------------------------------------------------------------------------8863 8864let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in8865class BaseSIMDIndexed<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc,8866 RegisterOperand dst_reg, RegisterOperand lhs_reg,8867 RegisterOperand rhs_reg, Operand vec_idx, string asm,8868 string apple_kind, string dst_kind, string lhs_kind,8869 string rhs_kind, list<dag> pattern>8870 : I<(outs dst_reg:$Rd), (ins lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx),8871 asm,8872 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" #8873 "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "", pattern>,8874 Sched<[WriteVd]> {8875 bits<5> Rd;8876 bits<5> Rn;8877 bits<5> Rm;8878 8879 let Inst{31} = 0;8880 let Inst{30} = Q;8881 let Inst{29} = U;8882 let Inst{28} = Scalar;8883 let Inst{27-24} = 0b1111;8884 let Inst{23-22} = size;8885 // Bit 21 must be set by the derived class.8886 let Inst{20-16} = Rm;8887 let Inst{15-12} = opc;8888 // Bit 11 must be set by the derived class.8889 let Inst{10} = 0;8890 let Inst{9-5} = Rn;8891 let Inst{4-0} = Rd;8892}8893 8894let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in8895class BaseSIMDIndexedTied<bit Q, bit U, bit Scalar, bits<2> size, bits<4> opc,8896 RegisterOperand dst_reg, RegisterOperand lhs_reg,8897 RegisterOperand rhs_reg, Operand vec_idx, string asm,8898 string apple_kind, string dst_kind, string lhs_kind,8899 string rhs_kind, list<dag> pattern>8900 : I<(outs dst_reg:$dst),8901 (ins dst_reg:$Rd, lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx), asm,8902 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind # "$idx" #8903 "|" # apple_kind # "\t$Rd, $Rn, $Rm$idx}", "$Rd = $dst", pattern>,8904 Sched<[WriteVd]> {8905 bits<5> Rd;8906 bits<5> Rn;8907 bits<5> Rm;8908 8909 let Inst{31} = 0;8910 let Inst{30} = Q;8911 let Inst{29} = U;8912 let Inst{28} = Scalar;8913 let Inst{27-24} = 0b1111;8914 let Inst{23-22} = size;8915 // Bit 21 must be set by the derived class.8916 let Inst{20-16} = Rm;8917 let Inst{15-12} = opc;8918 // Bit 11 must be set by the derived class.8919 let Inst{10} = 0;8920 let Inst{9-5} = Rn;8921 let Inst{4-0} = Rd;8922}8923 8924 8925//----------------------------------------------------------------------------8926// Armv8.6 BFloat16 Extension8927//----------------------------------------------------------------------------8928let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in {8929 8930class BaseSIMDThreeSameVectorBFDot<bit Q, bit U, string asm, string kind1,8931 string kind2, RegisterOperand RegType,8932 ValueType AccumType, ValueType InputType>8933 : BaseSIMDThreeSameVectorTied<Q, U, 0b010, 0b11111, RegType, asm, kind1, [(set (AccumType RegType:$dst),8934 (int_aarch64_neon_bfdot (AccumType RegType:$Rd),8935 (InputType RegType:$Rn),8936 (InputType RegType:$Rm)))]> {8937 let AsmString = !strconcat(asm,8938 "{\t$Rd" # kind1 # ", $Rn" # kind2 #8939 ", $Rm" # kind2 #8940 "|" # kind1 # "\t$Rd, $Rn, $Rm}");8941}8942 8943multiclass SIMDThreeSameVectorBFDot<bit U, string asm> {8944 def v4bf16 : BaseSIMDThreeSameVectorBFDot<0, U, asm, ".2s", ".4h", V64,8945 v2f32, v4bf16>;8946 def v8bf16 : BaseSIMDThreeSameVectorBFDot<1, U, asm, ".4s", ".8h", V128,8947 v4f32, v8bf16>;8948}8949 8950class BaseSIMDThreeSameVectorBF16DotI<bit Q, bit U, string asm,8951 string dst_kind, string lhs_kind,8952 string rhs_kind,8953 RegisterOperand RegType,8954 ValueType AccumType,8955 ValueType InputType>8956 : BaseSIMDIndexedTied<Q, U, 0b0, 0b01, 0b1111,8957 RegType, RegType, V128, VectorIndexS,8958 asm, "", dst_kind, lhs_kind, rhs_kind,8959 [(set (AccumType RegType:$dst),8960 (AccumType (int_aarch64_neon_bfdot8961 (AccumType RegType:$Rd),8962 (InputType RegType:$Rn),8963 (InputType (bitconvert (AccumType8964 (AArch64duplane32 (v4f32 V128:$Rm),8965 VectorIndexS:$idx)))))))]> {8966 8967 bits<2> idx;8968 let Inst{21} = idx{0}; // L8969 let Inst{11} = idx{1}; // H8970}8971 8972multiclass SIMDThreeSameVectorBF16DotI<bit U, string asm> {8973 8974 def v4bf16 : BaseSIMDThreeSameVectorBF16DotI<0, U, asm, ".2s", ".4h",8975 ".2h", V64, v2f32, v4bf16>;8976 def v8bf16 : BaseSIMDThreeSameVectorBF16DotI<1, U, asm, ".4s", ".8h",8977 ".2h", V128, v4f32, v8bf16>;8978}8979 8980let mayRaiseFPException = 1, Uses = [FPCR] in8981class SIMDBF16MLAL<bit Q, string asm, SDPatternOperator OpNode>8982 : BaseSIMDThreeSameVectorTied<Q, 0b1, 0b110, 0b11111, V128, asm, ".4s",8983 [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd),8984 (v8bf16 V128:$Rn),8985 (v8bf16 V128:$Rm)))]> {8986 let AsmString = !strconcat(asm, "{\t$Rd.4s, $Rn.8h, $Rm.8h|.4s\t$Rd, $Rn, $Rm}");8987}8988 8989let mayRaiseFPException = 1, Uses = [FPCR] in8990class SIMDBF16MLALIndex<bit Q, string asm, SDPatternOperator OpNode>8991 : I<(outs V128:$dst),8992 (ins V128:$Rd, V128:$Rn, V128_lo:$Rm, VectorIndexH:$idx), asm,8993 "{\t$Rd.4s, $Rn.8h, $Rm.h$idx}", "$Rd = $dst",8994 [(set (v4f32 V128:$dst),8995 (v4f32 (OpNode (v4f32 V128:$Rd),8996 (v8bf16 V128:$Rn),8997 (v8bf168998 (AArch64duplane16 (v8bf16 V128_lo:$Rm),8999 VectorIndexH:$idx)))))]>,9000 Sched<[WriteVq]> {9001 bits<5> Rd;9002 bits<5> Rn;9003 bits<4> Rm;9004 bits<3> idx;9005 9006 let Inst{31} = 0;9007 let Inst{30} = Q;9008 let Inst{29-22} = 0b00111111;9009 let Inst{21-20} = idx{1-0};9010 let Inst{19-16} = Rm;9011 let Inst{15-12} = 0b1111;9012 let Inst{11} = idx{2}; // H9013 let Inst{10} = 0;9014 let Inst{9-5} = Rn;9015 let Inst{4-0} = Rd;9016}9017 9018class SIMDThreeSameVectorBF16MatrixMul<string asm>9019 : BaseSIMDThreeSameVectorTied<1, 1, 0b010, 0b11101,9020 V128, asm, ".4s",9021 [(set (v4f32 V128:$dst),9022 (int_aarch64_neon_bfmmla (v4f32 V128:$Rd),9023 (v8bf16 V128:$Rn),9024 (v8bf16 V128:$Rm)))]> {9025 let AsmString = !strconcat(asm, "{\t$Rd.4s, $Rn.8h, $Rm.8h|.4s\t$Rd, $Rn, $Rm}");9026}9027 9028let mayRaiseFPException = 1, Uses = [FPCR] in9029class SIMD_BFCVTN9030 : BaseSIMDMixedTwoVector<0, 0, 0b10, 0b10110, V128, V64,9031 "bfcvtn", ".4h", ".4s",9032 [(set (v4bf16 V64:$Rd), (any_fpround (v4f32 V128:$Rn)))]>;9033 9034let mayRaiseFPException = 1, Uses = [FPCR] in9035class SIMD_BFCVTN29036 : BaseSIMDMixedTwoVectorTied<1, 0, 0b10, 0b10110, V128, V128,9037 "bfcvtn2", ".8h", ".4s", []>;9038 9039let mayRaiseFPException = 1, Uses = [FPCR] in9040class BF16ToSinglePrecision<string asm>9041 : I<(outs FPR16:$Rd), (ins FPR32:$Rn), asm, "\t$Rd, $Rn", "",9042 [(set (bf16 FPR16:$Rd), (any_fpround (f32 FPR32:$Rn)))]>,9043 Sched<[WriteFCvt]> {9044 bits<5> Rd;9045 bits<5> Rn;9046 let Inst{31-10} = 0b0001111001100011010000;9047 let Inst{9-5} = Rn;9048 let Inst{4-0} = Rd;9049}9050} // End of let mayStore = 0, mayLoad = 0, hasSideEffects = 09051 9052//----------------------------------------------------------------------------9053class BaseSIMDThreeSameVectorIndexB<bit Q, bit U, bits<2> sz, bits<4> opc,9054 string asm, string dst_kind,9055 RegisterOperand RegType,9056 RegisterOperand RegType_lo>9057 : BaseSIMDIndexedTied<Q, U, 0b0, sz, opc,9058 RegType, RegType, RegType_lo, VectorIndexB32b_timm,9059 asm, "", dst_kind, ".16b", ".b", []> {9060 9061 // idx = H:L:M9062 bits<4> idx;9063 let Inst{11} = idx{3};9064 let Inst{21-19} = idx{2-0};9065}9066 9067multiclass SIMDThreeSameVectorMLAIndex<bit Q, string asm, SDPatternOperator op> {9068 let Uses = [FPMR, FPCR], mayLoad = 1 in {9069 def v8f16 : BaseSIMDThreeSameVectorIndexB<Q, 0b0, 0b11, 0b0000, asm, ".8h",9070 V128, V128_0to7>;9071 }9072 9073 def : Pat<(v8f16 (op (v8f16 V128:$Rd), (v16i8 V128:$Rn), (v16i8 V128_0to7:$Rm), VectorIndexB32b_timm:$Idx)),9074 (!cast<Instruction>(NAME # v8f16) $Rd, $Rn, $Rm, $Idx)>;9075}9076 9077multiclass SIMDThreeSameVectorMLALIndex<bit Q, bits<2> sz, string asm, SDPatternOperator op> {9078 let Uses = [FPMR, FPCR], mayLoad = 1 in {9079 def v4f32 : BaseSIMDThreeSameVectorIndexB<Q, 0b1, sz, 0b1000, asm, ".4s",9080 V128, V128_0to7>;9081 }9082 9083 def : Pat<(v4f32 (op (v4f32 V128:$Rd), (v16i8 V128:$Rn), (v16i8 V128_0to7:$Rm), VectorIndexB32b_timm:$Idx)),9084 (!cast<Instruction>(NAME # v4f32) $Rd, $Rn, $Rm, $Idx)>;9085}9086 9087//----------------------------------------------------------------------------9088// Armv8.6 Matrix Multiply Extension9089//----------------------------------------------------------------------------9090 9091class SIMDThreeSameVectorMatMul<bit B, bit U, string asm, SDPatternOperator OpNode>9092 : BaseSIMDThreeSameVectorTied<1, U, 0b100, {0b1010, B}, V128, asm, ".4s",9093 [(set (v4i32 V128:$dst), (OpNode (v4i32 V128:$Rd),9094 (v16i8 V128:$Rn),9095 (v16i8 V128:$Rm)))]> {9096 let AsmString = asm # "{\t$Rd.4s, $Rn.16b, $Rm.16b|.4s\t$Rd, $Rn, $Rm}";9097}9098 9099//----------------------------------------------------------------------------9100// ARMv8.2-A Dot Product Instructions (Indexed)9101class BaseSIMDThreeSameVectorIndexS<bit Q, bit U, bits<2> size, bits<4> opc, string asm,9102 string dst_kind, string lhs_kind, string rhs_kind,9103 RegisterOperand RegType,9104 ValueType AccumType, ValueType InputType,9105 AsmVectorIndexOpnd VIdx,9106 SDPatternOperator OpNode> :9107 BaseSIMDIndexedTied<Q, U, 0b0, size, opc, RegType, RegType, V128,9108 VIdx, asm, "", dst_kind, lhs_kind, rhs_kind,9109 [(set (AccumType RegType:$dst),9110 (AccumType (OpNode (AccumType RegType:$Rd),9111 (InputType RegType:$Rn),9112 (InputType (bitconvert (AccumType9113 (AArch64duplane32 (v4i32 V128:$Rm),9114 VIdx:$idx)))))))]> {9115 bits<2> idx;9116 let Inst{21} = idx{0}; // L9117 let Inst{11} = idx{1}; // H9118}9119 9120multiclass SIMDThreeSameVectorDotIndex<bit U, bit Mixed, bits<2> size, string asm,9121 SDPatternOperator OpNode> {9122 def v8i8 : BaseSIMDThreeSameVectorIndexS<0, U, size, {0b111, Mixed}, asm, ".2s", ".8b", ".4b",9123 V64, v2i32, v8i8, VectorIndexS, OpNode>;9124 def v16i8 : BaseSIMDThreeSameVectorIndexS<1, U, size, {0b111, Mixed}, asm, ".4s", ".16b", ".4b",9125 V128, v4i32, v16i8, VectorIndexS, OpNode>;9126}9127 9128multiclass SIMD_FP8_Dot4_Index<string asm, SDPatternOperator op> {9129 let Uses = [FPMR, FPCR], mayLoad = 1 in {9130 def v2f32 : BaseSIMDThreeSameVectorIndexS<0b0, 0b0, 0b00, 0b0000, asm, ".2s", ".8b", ".4b",9131 V64, v2f32, v8i8, VectorIndexS32b_timm, null_frag>;9132 def v4f32 : BaseSIMDThreeSameVectorIndexS<0b1, 0b0, 0b00, 0b0000, asm, ".4s", ".16b",".4b",9133 V128, v4f32, v16i8, VectorIndexS32b_timm, null_frag>;9134 }9135 9136 def : Pat<(v2f32 (op (v2f32 V64:$Rd), (v8i8 V64:$Rn), (v16i8 V128:$Rm), VectorIndexS32b_timm:$Idx)),9137 (!cast<Instruction>(NAME # v2f32) $Rd, $Rn, $Rm, $Idx)>;9138 9139 def : Pat<(v4f32 (op (v4f32 V128:$Rd), (v16i8 V128:$Rn), (v16i8 V128:$Rm), VectorIndexS32b_timm:$Idx)),9140 (!cast<Instruction>(NAME # v4f32) $Rd, $Rn, $Rm, $Idx)>;9141}9142 9143// ARMv8.2-A Fused Multiply Add-Long Instructions (Indexed)9144let mayRaiseFPException = 1, Uses = [FPCR] in9145class BaseSIMDThreeSameVectorIndexH<bit Q, bit U, bits<2> sz, bits<4> opc, string asm,9146 string dst_kind, string lhs_kind,9147 string rhs_kind, RegisterOperand RegType,9148 RegisterOperand RegType_lo, ValueType AccumType,9149 ValueType InputType, AsmVectorIndexOpnd VIdx,9150 SDPatternOperator OpNode> :9151 BaseSIMDIndexedTied<Q, U, 0, sz, opc, RegType, RegType, RegType_lo,9152 VIdx, asm, "", dst_kind, lhs_kind, rhs_kind,9153 [(set (AccumType RegType:$dst),9154 (AccumType (OpNode (AccumType RegType:$Rd),9155 (InputType RegType:$Rn),9156 (InputType (AArch64duplane16 (v8f16 V128_lo:$Rm),9157 VIdx:$idx)))))]> {9158 // idx = H:L:M9159 bits<3> idx;9160 let Inst{11} = idx{2}; // H9161 let Inst{21} = idx{1}; // L9162 let Inst{20} = idx{0}; // M9163}9164 9165multiclass SIMDThreeSameVectorFMLIndex<bit U, bits<4> opc, string asm,9166 SDPatternOperator OpNode> {9167 def v4f16 : BaseSIMDThreeSameVectorIndexH<0, U, 0b10, opc, asm, ".2s", ".2h", ".h",9168 V64, V128_lo, v2f32, v4f16, VectorIndexH, OpNode>;9169 def v8f16 : BaseSIMDThreeSameVectorIndexH<1, U, 0b10, opc, asm, ".4s", ".4h", ".h",9170 V128, V128_lo, v4f32, v8f16, VectorIndexH, OpNode>;9171}9172 9173multiclass SIMDThreeSameVectorFDOTIndex<string asm> {9174 def v4f16_v2f32 : BaseSIMDThreeSameVectorIndexS<0b0, 0b0, 0b01, 0b1001, asm, ".2s", ".4h", ".2h",9175 V64, v2f32, v4f16, VectorIndexS, null_frag>;9176 def v8f16_v4f32 : BaseSIMDThreeSameVectorIndexS<0b1, 0b0, 0b01, 0b1001, asm, ".4s", ".8h",".2h",9177 V128, v4f32, v8f16, VectorIndexS, null_frag>;9178}9179 9180//----------------------------------------------------------------------------9181// FP8 Advanced SIMD vector x indexed element9182multiclass SIMD_FP8_Dot2_Index<string asm, SDPatternOperator op> {9183 let Uses = [FPMR, FPCR], mayLoad = 1 in { 9184 def v4f16 : BaseSIMDThreeSameVectorIndexH<0b0, 0b0, 0b01, 0b0000, asm, ".4h", ".8b", ".2b",9185 V64, V128_lo, v4f16, v8i8, VectorIndexH32b_timm, null_frag>;9186 def v8f16 : BaseSIMDThreeSameVectorIndexH<0b1, 0b0, 0b01, 0b0000, asm, ".8h", ".16b", ".2b",9187 V128, V128_lo, v8f16, v16i8, VectorIndexH32b_timm, null_frag>;9188 }9189 def : Pat<(v4f16 (op (v4f16 V64:$Rd), (v8i8 V64:$Rn), (v16i8 V128_lo:$Rm), VectorIndexH32b_timm:$Idx)),9190 (!cast<Instruction>(NAME # v4f16) $Rd, $Rn, $Rm, $Idx)>;9191 9192 def : Pat<(v8f16 (op (v8f16 V128:$Rd), (v16i8 V128:$Rn), (v16i8 V128_lo:$Rm), VectorIndexH32b_timm:$Idx)),9193 (!cast<Instruction>(NAME # v8f16) $Rd, $Rn, $Rm, $Idx)>;9194}9195 9196multiclass SIMDFPIndexed<bit U, bits<4> opc, string asm,9197 SDPatternOperator OpNode> {9198 let mayRaiseFPException = 1, Uses = [FPCR] in {9199 let Predicates = [HasNEON, HasFullFP16] in {9200 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b00, opc,9201 V64, V64,9202 V128_lo, VectorIndexH,9203 asm, ".4h", ".4h", ".4h", ".h",9204 [(set (v4f16 V64:$Rd),9205 (OpNode (v4f16 V64:$Rn),9206 (dup_v8f16 (v8f16 V128_lo:$Rm), VectorIndexH:$idx)))]> {9207 bits<3> idx;9208 let Inst{11} = idx{2};9209 let Inst{21} = idx{1};9210 let Inst{20} = idx{0};9211 }9212 9213 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b00, opc,9214 V128, V128,9215 V128_lo, VectorIndexH,9216 asm, ".8h", ".8h", ".8h", ".h",9217 [(set (v8f16 V128:$Rd),9218 (OpNode (v8f16 V128:$Rn),9219 (v8f16 (AArch64duplane16 (v8f16 V128_lo:$Rm), VectorIndexH:$idx))))]> {9220 bits<3> idx;9221 let Inst{11} = idx{2};9222 let Inst{21} = idx{1};9223 let Inst{20} = idx{0};9224 }9225 } // Predicates = [HasNEON, HasFullFP16]9226 9227 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,9228 V64, V64,9229 V128, VectorIndexS,9230 asm, ".2s", ".2s", ".2s", ".s",9231 [(set (v2f32 V64:$Rd),9232 (OpNode (v2f32 V64:$Rn),9233 (dup_v4f32 (v4f32 V128:$Rm), VectorIndexS:$idx)))]> {9234 bits<2> idx;9235 let Inst{11} = idx{1};9236 let Inst{21} = idx{0};9237 }9238 9239 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,9240 V128, V128,9241 V128, VectorIndexS,9242 asm, ".4s", ".4s", ".4s", ".s",9243 [(set (v4f32 V128:$Rd),9244 (OpNode (v4f32 V128:$Rn),9245 (v4f32 (AArch64duplane32 (v4f32 V128:$Rm), VectorIndexS:$idx))))]> {9246 bits<2> idx;9247 let Inst{11} = idx{1};9248 let Inst{21} = idx{0};9249 }9250 9251 def v2i64_indexed : BaseSIMDIndexed<1, U, 0, 0b11, opc,9252 V128, V128,9253 V128, VectorIndexD,9254 asm, ".2d", ".2d", ".2d", ".d",9255 [(set (v2f64 V128:$Rd),9256 (OpNode (v2f64 V128:$Rn),9257 (v2f64 (AArch64duplane64 (v2f64 V128:$Rm), VectorIndexD:$idx))))]> {9258 bits<1> idx;9259 let Inst{11} = idx{0};9260 let Inst{21} = 0;9261 }9262 9263 let Predicates = [HasNEON, HasFullFP16] in {9264 def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b00, opc,9265 FPR16Op, FPR16Op, V128_lo, VectorIndexH,9266 asm, ".h", "", "", ".h",9267 [(set (f16 FPR16Op:$Rd),9268 (OpNode (f16 FPR16Op:$Rn),9269 (f16 (vector_extract (v8f16 V128_lo:$Rm),9270 VectorIndexH:$idx))))]> {9271 bits<3> idx;9272 let Inst{11} = idx{2};9273 let Inst{21} = idx{1};9274 let Inst{20} = idx{0};9275 }9276 } // Predicates = [HasNEON, HasFullFP16]9277 9278 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc,9279 FPR32Op, FPR32Op, V128, VectorIndexS,9280 asm, ".s", "", "", ".s",9281 [(set (f32 FPR32Op:$Rd),9282 (OpNode (f32 FPR32Op:$Rn),9283 (f32 (vector_extract (v4f32 V128:$Rm),9284 VectorIndexS:$idx))))]> {9285 bits<2> idx;9286 let Inst{11} = idx{1};9287 let Inst{21} = idx{0};9288 }9289 9290 def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b11, opc,9291 FPR64Op, FPR64Op, V128, VectorIndexD,9292 asm, ".d", "", "", ".d",9293 [(set (f64 FPR64Op:$Rd),9294 (OpNode (f64 FPR64Op:$Rn),9295 (f64 (vector_extract (v2f64 V128:$Rm),9296 VectorIndexD:$idx))))]> {9297 bits<1> idx;9298 let Inst{11} = idx{0};9299 let Inst{21} = 0;9300 }9301 } // mayRaiseFPException = 1, Uses = [FPCR]9302 9303 let Predicates = [HasNEON, HasFullFP16] in {9304 def : Pat<(f16 (OpNode9305 (f16 (vector_extract (v8f16 V128:$Rn), (i64 0))),9306 (f16 (vector_extract (v8f16 V128:$Rm), VectorIndexH:$idx)))),9307 (!cast<Instruction>(NAME # v1i16_indexed)9308 (f16 (EXTRACT_SUBREG V128:$Rn, hsub)), V128:$Rm, VectorIndexH:$idx)>;9309 }9310 9311 let Predicates = [HasNEON] in {9312 def : Pat<(f32 (OpNode9313 (f32 (vector_extract (v4f32 V128:$Rn), (i64 0))),9314 (f32 (vector_extract (v4f32 V128:$Rm), VectorIndexS:$idx)))),9315 (!cast<Instruction>(NAME # v1i32_indexed)9316 (EXTRACT_SUBREG V128:$Rn, ssub), V128:$Rm, VectorIndexS:$idx)>;9317 9318 def : Pat<(f64 (OpNode9319 (f64 (vector_extract (v2f64 V128:$Rn), (i64 0))),9320 (f64 (vector_extract (v2f64 V128:$Rm), VectorIndexD:$idx)))),9321 (!cast<Instruction>(NAME # v1i64_indexed)9322 (EXTRACT_SUBREG V128:$Rn, dsub), V128:$Rm, VectorIndexD:$idx)>;9323 }9324}9325 9326multiclass SIMDFPIndexedTiedPatterns<string INST, SDPatternOperator OpNode> {9327 let Predicates = [HasNEON, HasFullFP16] in {9328 // Patterns for f16: DUPLANE, DUP scalar and vector_extract.9329 def : Pat<(v8f16 (OpNode (v8f16 V128:$Rd), (v8f16 V128:$Rn),9330 (AArch64duplane16 (v8f16 V128_lo:$Rm),9331 VectorIndexH:$idx))),9332 (!cast<Instruction>(INST # "v8i16_indexed")9333 V128:$Rd, V128:$Rn, V128_lo:$Rm, VectorIndexH:$idx)>;9334 def : Pat<(v8f16 (OpNode (v8f16 V128:$Rd), (v8f16 V128:$Rn),9335 (AArch64dup (f16 FPR16Op_lo:$Rm)))),9336 (!cast<Instruction>(INST # "v8i16_indexed") V128:$Rd, V128:$Rn,9337 (SUBREG_TO_REG (i32 0), (f16 FPR16Op_lo:$Rm), hsub), (i64 0))>;9338 9339 def : Pat<(v4f16 (OpNode (v4f16 V64:$Rd), (v4f16 V64:$Rn),9340 (AArch64duplane16 (v8f16 V128_lo:$Rm),9341 VectorIndexH:$idx))),9342 (!cast<Instruction>(INST # "v4i16_indexed")9343 V64:$Rd, V64:$Rn, V128_lo:$Rm, VectorIndexH:$idx)>;9344 def : Pat<(v4f16 (OpNode (v4f16 V64:$Rd), (v4f16 V64:$Rn),9345 (AArch64dup (f16 FPR16Op_lo:$Rm)))),9346 (!cast<Instruction>(INST # "v4i16_indexed") V64:$Rd, V64:$Rn,9347 (SUBREG_TO_REG (i32 0), (f16 FPR16Op_lo:$Rm), hsub), (i64 0))>;9348 9349 def : Pat<(f16 (OpNode (f16 FPR16:$Rd), (f16 FPR16:$Rn),9350 (vector_extract (v8f16 V128_lo:$Rm), VectorIndexH:$idx))),9351 (!cast<Instruction>(INST # "v1i16_indexed") FPR16:$Rd, FPR16:$Rn,9352 V128_lo:$Rm, VectorIndexH:$idx)>;9353 def : Pat<(f16 (OpNode (f16 FPR16:$Rd),9354 (vector_extract (v8f16 V128:$Rn), (i64 0)),9355 (vector_extract (v8f16 V128_lo:$Rm), VectorIndexH:$idx))),9356 (!cast<Instruction>(INST # "v1i16_indexed") FPR16:$Rd,9357 (f16 (EXTRACT_SUBREG V128:$Rn, hsub)), V128_lo:$Rm, VectorIndexH:$idx)>;9358 } // Predicates = [HasNEON, HasFullFP16]9359 9360 // 2 variants for the .2s version: DUPLANE from 128-bit and DUP scalar.9361 def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn),9362 (AArch64duplane32 (v4f32 V128:$Rm),9363 VectorIndexS:$idx))),9364 (!cast<Instruction>(INST # v2i32_indexed)9365 V64:$Rd, V64:$Rn, V128:$Rm, VectorIndexS:$idx)>;9366 def : Pat<(v2f32 (OpNode (v2f32 V64:$Rd), (v2f32 V64:$Rn),9367 (AArch64dup (f32 FPR32Op:$Rm)))),9368 (!cast<Instruction>(INST # "v2i32_indexed") V64:$Rd, V64:$Rn,9369 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>;9370 9371 9372 // 2 variants for the .4s version: DUPLANE from 128-bit and DUP scalar.9373 def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn),9374 (AArch64duplane32 (v4f32 V128:$Rm),9375 VectorIndexS:$idx))),9376 (!cast<Instruction>(INST # "v4i32_indexed")9377 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>;9378 def : Pat<(v4f32 (OpNode (v4f32 V128:$Rd), (v4f32 V128:$Rn),9379 (AArch64dup (f32 FPR32Op:$Rm)))),9380 (!cast<Instruction>(INST # "v4i32_indexed") V128:$Rd, V128:$Rn,9381 (SUBREG_TO_REG (i32 0), FPR32Op:$Rm, ssub), (i64 0))>;9382 9383 // 2 variants for the .2d version: DUPLANE from 128-bit and DUP scalar.9384 def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn),9385 (AArch64duplane64 (v2f64 V128:$Rm),9386 VectorIndexD:$idx))),9387 (!cast<Instruction>(INST # "v2i64_indexed")9388 V128:$Rd, V128:$Rn, V128:$Rm, VectorIndexS:$idx)>;9389 def : Pat<(v2f64 (OpNode (v2f64 V128:$Rd), (v2f64 V128:$Rn),9390 (AArch64dup (f64 FPR64Op:$Rm)))),9391 (!cast<Instruction>(INST # "v2i64_indexed") V128:$Rd, V128:$Rn,9392 (SUBREG_TO_REG (i32 0), FPR64Op:$Rm, dsub), (i64 0))>;9393 9394 // Covers 2 variants for 32-bit scalar version: extract from .2s or from .4s9395 def : Pat<(f32 (OpNode (f32 FPR32:$Rd), (f32 FPR32:$Rn),9396 (vector_extract (v4f32 V128:$Rm), VectorIndexS:$idx))),9397 (!cast<Instruction>(INST # "v1i32_indexed") FPR32:$Rd, FPR32:$Rn,9398 V128:$Rm, VectorIndexS:$idx)>;9399 def : Pat<(f32 (OpNode (f32 FPR32:$Rd),9400 (vector_extract (v4f32 V128:$Rn), (i64 0)),9401 (vector_extract (v4f32 V128:$Rm), VectorIndexS:$idx))),9402 (!cast<Instruction>(INST # "v1i32_indexed") FPR32:$Rd,9403 (f32 (EXTRACT_SUBREG V128:$Rn, ssub)), V128:$Rm, VectorIndexS:$idx)>;9404 9405 // 1 variant for 64-bit scalar version: extract from .1d or from .2d9406 def : Pat<(f64 (OpNode (f64 FPR64:$Rd), (f64 FPR64:$Rn),9407 (vector_extract (v2f64 V128:$Rm), VectorIndexD:$idx))),9408 (!cast<Instruction>(INST # "v1i64_indexed") FPR64:$Rd, FPR64:$Rn,9409 V128:$Rm, VectorIndexD:$idx)>;9410 def : Pat<(f64 (OpNode (f64 FPR64:$Rd),9411 (vector_extract (v2f64 V128:$Rn), (i64 0)),9412 (vector_extract (v2f64 V128:$Rm), VectorIndexD:$idx))),9413 (!cast<Instruction>(INST # "v1i64_indexed") FPR64:$Rd,9414 (f64 (EXTRACT_SUBREG V128:$Rn, dsub)), V128:$Rm, VectorIndexD:$idx)>;9415}9416 9417let mayRaiseFPException = 1, Uses = [FPCR] in9418multiclass SIMDFPIndexedTied<bit U, bits<4> opc, string asm> {9419 let Predicates = [HasNEON, HasFullFP16] in {9420 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b00, opc, V64, V64,9421 V128_lo, VectorIndexH,9422 asm, ".4h", ".4h", ".4h", ".h", []> {9423 bits<3> idx;9424 let Inst{11} = idx{2};9425 let Inst{21} = idx{1};9426 let Inst{20} = idx{0};9427 }9428 9429 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b00, opc,9430 V128, V128,9431 V128_lo, VectorIndexH,9432 asm, ".8h", ".8h", ".8h", ".h", []> {9433 bits<3> idx;9434 let Inst{11} = idx{2};9435 let Inst{21} = idx{1};9436 let Inst{20} = idx{0};9437 }9438 } // Predicates = [HasNEON, HasFullFP16]9439 9440 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc, V64, V64,9441 V128, VectorIndexS,9442 asm, ".2s", ".2s", ".2s", ".s", []> {9443 bits<2> idx;9444 let Inst{11} = idx{1};9445 let Inst{21} = idx{0};9446 }9447 9448 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,9449 V128, V128,9450 V128, VectorIndexS,9451 asm, ".4s", ".4s", ".4s", ".s", []> {9452 bits<2> idx;9453 let Inst{11} = idx{1};9454 let Inst{21} = idx{0};9455 }9456 9457 def v2i64_indexed : BaseSIMDIndexedTied<1, U, 0, 0b11, opc,9458 V128, V128,9459 V128, VectorIndexD,9460 asm, ".2d", ".2d", ".2d", ".d", []> {9461 bits<1> idx;9462 let Inst{11} = idx{0};9463 let Inst{21} = 0;9464 }9465 9466 let Predicates = [HasNEON, HasFullFP16] in {9467 def v1i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b00, opc,9468 FPR16Op, FPR16Op, V128_lo, VectorIndexH,9469 asm, ".h", "", "", ".h", []> {9470 bits<3> idx;9471 let Inst{11} = idx{2};9472 let Inst{21} = idx{1};9473 let Inst{20} = idx{0};9474 }9475 } // Predicates = [HasNEON, HasFullFP16]9476 9477 def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc,9478 FPR32Op, FPR32Op, V128, VectorIndexS,9479 asm, ".s", "", "", ".s", []> {9480 bits<2> idx;9481 let Inst{11} = idx{1};9482 let Inst{21} = idx{0};9483 }9484 9485 def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b11, opc,9486 FPR64Op, FPR64Op, V128, VectorIndexD,9487 asm, ".d", "", "", ".d", []> {9488 bits<1> idx;9489 let Inst{11} = idx{0};9490 let Inst{21} = 0;9491 }9492}9493 9494multiclass SIMDIndexedHSPatterns<SDPatternOperator OpNodeLane,9495 SDPatternOperator OpNodeLaneQ> {9496 9497 def : Pat<(v4i16 (OpNodeLane9498 (v4i16 V64:$Rn), (v4i16 V64_lo:$Rm),9499 VectorIndexS32b:$idx)),9500 (!cast<Instruction>(NAME # v4i16_indexed) $Rn,9501 (SUBREG_TO_REG (i32 0), (v4i16 V64_lo:$Rm), dsub),9502 (UImmS1XForm $idx))>;9503 9504 def : Pat<(v4i16 (OpNodeLaneQ9505 (v4i16 V64:$Rn), (v8i16 V128_lo:$Rm),9506 VectorIndexH32b:$idx)),9507 (!cast<Instruction>(NAME # v4i16_indexed) $Rn, $Rm,9508 (UImmS1XForm $idx))>;9509 9510 def : Pat<(v8i16 (OpNodeLane9511 (v8i16 V128:$Rn), (v4i16 V64_lo:$Rm),9512 VectorIndexS32b:$idx)),9513 (!cast<Instruction>(NAME # v8i16_indexed) $Rn,9514 (SUBREG_TO_REG (i32 0), $Rm, dsub),9515 (UImmS1XForm $idx))>;9516 9517 def : Pat<(v8i16 (OpNodeLaneQ9518 (v8i16 V128:$Rn), (v8i16 V128_lo:$Rm),9519 VectorIndexH32b:$idx)),9520 (!cast<Instruction>(NAME # v8i16_indexed) $Rn, $Rm,9521 (UImmS1XForm $idx))>;9522 9523 def : Pat<(v2i32 (OpNodeLane9524 (v2i32 V64:$Rn), (v2i32 V64:$Rm),9525 VectorIndexD32b:$idx)),9526 (!cast<Instruction>(NAME # v2i32_indexed) $Rn,9527 (SUBREG_TO_REG (i32 0), (v2i32 V64_lo:$Rm), dsub),9528 (UImmS1XForm $idx))>;9529 9530 def : Pat<(v2i32 (OpNodeLaneQ9531 (v2i32 V64:$Rn), (v4i32 V128:$Rm),9532 VectorIndexS32b:$idx)),9533 (!cast<Instruction>(NAME # v2i32_indexed) $Rn, $Rm,9534 (UImmS1XForm $idx))>;9535 9536 def : Pat<(v4i32 (OpNodeLane9537 (v4i32 V128:$Rn), (v2i32 V64:$Rm),9538 VectorIndexD32b:$idx)),9539 (!cast<Instruction>(NAME # v4i32_indexed) $Rn,9540 (SUBREG_TO_REG (i32 0), $Rm, dsub),9541 (UImmS1XForm $idx))>;9542 9543 def : Pat<(v4i32 (OpNodeLaneQ9544 (v4i32 V128:$Rn),9545 (v4i32 V128:$Rm),9546 VectorIndexS32b:$idx)),9547 (!cast<Instruction>(NAME # v4i32_indexed) $Rn, $Rm,9548 (UImmS1XForm $idx))>;9549 9550}9551 9552multiclass SIMDIndexedHS<bit U, bits<4> opc, string asm,9553 SDPatternOperator OpNode> {9554 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc, V64, V64,9555 V128_lo, VectorIndexH,9556 asm, ".4h", ".4h", ".4h", ".h",9557 [(set (v4i16 V64:$Rd),9558 (OpNode (v4i16 V64:$Rn),9559 (dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))]> {9560 bits<3> idx;9561 let Inst{11} = idx{2};9562 let Inst{21} = idx{1};9563 let Inst{20} = idx{0};9564 }9565 9566 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,9567 V128, V128,9568 V128_lo, VectorIndexH,9569 asm, ".8h", ".8h", ".8h", ".h",9570 [(set (v8i16 V128:$Rd),9571 (OpNode (v8i16 V128:$Rn),9572 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {9573 bits<3> idx;9574 let Inst{11} = idx{2};9575 let Inst{21} = idx{1};9576 let Inst{20} = idx{0};9577 }9578 9579 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,9580 V64, V64,9581 V128, VectorIndexS,9582 asm, ".2s", ".2s", ".2s", ".s",9583 [(set (v2i32 V64:$Rd),9584 (OpNode (v2i32 V64:$Rn),9585 (dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))]> {9586 bits<2> idx;9587 let Inst{11} = idx{1};9588 let Inst{21} = idx{0};9589 }9590 9591 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,9592 V128, V128,9593 V128, VectorIndexS,9594 asm, ".4s", ".4s", ".4s", ".s",9595 [(set (v4i32 V128:$Rd),9596 (OpNode (v4i32 V128:$Rn),9597 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {9598 bits<2> idx;9599 let Inst{11} = idx{1};9600 let Inst{21} = idx{0};9601 }9602 9603 def v1i16_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc,9604 FPR16Op, FPR16Op, V128_lo, VectorIndexH,9605 asm, ".h", "", "", ".h", []> {9606 bits<3> idx;9607 let Inst{11} = idx{2};9608 let Inst{21} = idx{1};9609 let Inst{20} = idx{0};9610 }9611 9612 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc,9613 FPR32Op, FPR32Op, V128, VectorIndexS,9614 asm, ".s", "", "", ".s",9615 [(set (i32 FPR32Op:$Rd),9616 (OpNode FPR32Op:$Rn,9617 (i32 (vector_extract (v4i32 V128:$Rm),9618 VectorIndexS:$idx))))]> {9619 bits<2> idx;9620 let Inst{11} = idx{1};9621 let Inst{21} = idx{0};9622 }9623}9624 9625multiclass SIMDVectorIndexedHS<bit U, bits<4> opc, string asm,9626 SDPatternOperator OpNode> {9627 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc,9628 V64, V64,9629 V128_lo, VectorIndexH,9630 asm, ".4h", ".4h", ".4h", ".h",9631 [(set (v4i16 V64:$Rd),9632 (OpNode (v4i16 V64:$Rn),9633 (dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))]> {9634 bits<3> idx;9635 let Inst{11} = idx{2};9636 let Inst{21} = idx{1};9637 let Inst{20} = idx{0};9638 }9639 9640 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,9641 V128, V128,9642 V128_lo, VectorIndexH,9643 asm, ".8h", ".8h", ".8h", ".h",9644 [(set (v8i16 V128:$Rd),9645 (OpNode (v8i16 V128:$Rn),9646 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {9647 bits<3> idx;9648 let Inst{11} = idx{2};9649 let Inst{21} = idx{1};9650 let Inst{20} = idx{0};9651 }9652 9653 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,9654 V64, V64,9655 V128, VectorIndexS,9656 asm, ".2s", ".2s", ".2s", ".s",9657 [(set (v2i32 V64:$Rd),9658 (OpNode (v2i32 V64:$Rn),9659 (dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))]> {9660 bits<2> idx;9661 let Inst{11} = idx{1};9662 let Inst{21} = idx{0};9663 }9664 9665 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,9666 V128, V128,9667 V128, VectorIndexS,9668 asm, ".4s", ".4s", ".4s", ".s",9669 [(set (v4i32 V128:$Rd),9670 (OpNode (v4i32 V128:$Rn),9671 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {9672 bits<2> idx;9673 let Inst{11} = idx{1};9674 let Inst{21} = idx{0};9675 }9676}9677 9678multiclass SIMDVectorIndexedHSTied<bit U, bits<4> opc, string asm,9679 SDPatternOperator OpNode> {9680 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc, V64, V64,9681 V128_lo, VectorIndexH,9682 asm, ".4h", ".4h", ".4h", ".h",9683 [(set (v4i16 V64:$dst),9684 (OpNode (v4i16 V64:$Rd),(v4i16 V64:$Rn),9685 (dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))]> {9686 bits<3> idx;9687 let Inst{11} = idx{2};9688 let Inst{21} = idx{1};9689 let Inst{20} = idx{0};9690 }9691 9692 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,9693 V128, V128,9694 V128_lo, VectorIndexH,9695 asm, ".8h", ".8h", ".8h", ".h",9696 [(set (v8i16 V128:$dst),9697 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn),9698 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx))))]> {9699 bits<3> idx;9700 let Inst{11} = idx{2};9701 let Inst{21} = idx{1};9702 let Inst{20} = idx{0};9703 }9704 9705 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,9706 V64, V64,9707 V128, VectorIndexS,9708 asm, ".2s", ".2s", ".2s", ".s",9709 [(set (v2i32 V64:$dst),9710 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn),9711 (dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))]> {9712 bits<2> idx;9713 let Inst{11} = idx{1};9714 let Inst{21} = idx{0};9715 }9716 9717 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,9718 V128, V128,9719 V128, VectorIndexS,9720 asm, ".4s", ".4s", ".4s", ".s",9721 [(set (v4i32 V128:$dst),9722 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),9723 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {9724 bits<2> idx;9725 let Inst{11} = idx{1};9726 let Inst{21} = idx{0};9727 }9728}9729 9730multiclass SIMDIndexedLongSD<bit U, bits<4> opc, string asm,9731 SDPatternOperator OpNode> {9732 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc,9733 V128, V64,9734 V128_lo, VectorIndexH,9735 asm, ".4s", ".4s", ".4h", ".h",9736 [(set (v4i32 V128:$Rd),9737 (OpNode (v4i16 V64:$Rn),9738 (dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))]> {9739 bits<3> idx;9740 let Inst{11} = idx{2};9741 let Inst{21} = idx{1};9742 let Inst{20} = idx{0};9743 }9744 9745 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,9746 V128, V128,9747 V128_lo, VectorIndexH,9748 asm#"2", ".4s", ".4s", ".8h", ".h",9749 [(set (v4i32 V128:$Rd),9750 (OpNode (extract_high_v8i16 (v8i16 V128:$Rn)),9751 (extract_high_dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))]> {9752 9753 bits<3> idx;9754 let Inst{11} = idx{2};9755 let Inst{21} = idx{1};9756 let Inst{20} = idx{0};9757 }9758 9759 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,9760 V128, V64,9761 V128, VectorIndexS,9762 asm, ".2d", ".2d", ".2s", ".s",9763 [(set (v2i64 V128:$Rd),9764 (OpNode (v2i32 V64:$Rn),9765 (dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))]> {9766 bits<2> idx;9767 let Inst{11} = idx{1};9768 let Inst{21} = idx{0};9769 }9770 9771 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,9772 V128, V128,9773 V128, VectorIndexS,9774 asm#"2", ".2d", ".2d", ".4s", ".s",9775 [(set (v2i64 V128:$Rd),9776 (OpNode (extract_high_v4i32 (v4i32 V128:$Rn)),9777 (extract_high_dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))]> {9778 bits<2> idx;9779 let Inst{11} = idx{1};9780 let Inst{21} = idx{0};9781 }9782 9783 def v1i32_indexed : BaseSIMDIndexed<1, U, 1, 0b01, opc,9784 FPR32Op, FPR16Op, V128_lo, VectorIndexH,9785 asm, ".h", "", "", ".h", []> {9786 bits<3> idx;9787 let Inst{11} = idx{2};9788 let Inst{21} = idx{1};9789 let Inst{20} = idx{0};9790 }9791 9792 def v1i64_indexed : BaseSIMDIndexed<1, U, 1, 0b10, opc,9793 FPR64Op, FPR32Op, V128, VectorIndexS,9794 asm, ".s", "", "", ".s", []> {9795 bits<2> idx;9796 let Inst{11} = idx{1};9797 let Inst{21} = idx{0};9798 }9799}9800 9801multiclass SIMDIndexedLongSQDMLXSDTied<bit U, bits<4> opc, string asm,9802 SDPatternOperator VecAcc,9803 SDPatternOperator ScalAcc> {9804 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc,9805 V128, V64,9806 V128_lo, VectorIndexH,9807 asm, ".4s", ".4s", ".4h", ".h",9808 [(set (v4i32 V128:$dst),9809 (VecAcc (v4i32 V128:$Rd),9810 (v4i32 (int_aarch64_neon_sqdmull9811 (v4i16 V64:$Rn),9812 (dup_v8i16 (v8i16 V128_lo:$Rm),9813 VectorIndexH:$idx)))))]> {9814 bits<3> idx;9815 let Inst{11} = idx{2};9816 let Inst{21} = idx{1};9817 let Inst{20} = idx{0};9818 }9819 9820 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,9821 V128, V128,9822 V128_lo, VectorIndexH,9823 asm#"2", ".4s", ".4s", ".8h", ".h",9824 [(set (v4i32 V128:$dst),9825 (VecAcc (v4i32 V128:$Rd),9826 (v4i32 (int_aarch64_neon_sqdmull9827 (extract_high_v8i16 (v8i16 V128:$Rn)),9828 (extract_high_dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))))]> {9829 bits<3> idx;9830 let Inst{11} = idx{2};9831 let Inst{21} = idx{1};9832 let Inst{20} = idx{0};9833 }9834 9835 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,9836 V128, V64,9837 V128, VectorIndexS,9838 asm, ".2d", ".2d", ".2s", ".s",9839 [(set (v2i64 V128:$dst),9840 (VecAcc (v2i64 V128:$Rd),9841 (v2i64 (int_aarch64_neon_sqdmull9842 (v2i32 V64:$Rn),9843 (dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))))]> {9844 bits<2> idx;9845 let Inst{11} = idx{1};9846 let Inst{21} = idx{0};9847 }9848 9849 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,9850 V128, V128,9851 V128, VectorIndexS,9852 asm#"2", ".2d", ".2d", ".4s", ".s",9853 [(set (v2i64 V128:$dst),9854 (VecAcc (v2i64 V128:$Rd),9855 (v2i64 (int_aarch64_neon_sqdmull9856 (extract_high_v4i32 (v4i32 V128:$Rn)),9857 (extract_high_dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))))]> {9858 bits<2> idx;9859 let Inst{11} = idx{1};9860 let Inst{21} = idx{0};9861 }9862 9863 def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc,9864 FPR32Op, FPR16Op, V128_lo, VectorIndexH,9865 asm, ".h", "", "", ".h", []> {9866 bits<3> idx;9867 let Inst{11} = idx{2};9868 let Inst{21} = idx{1};9869 let Inst{20} = idx{0};9870 }9871 9872 def : Pat<(i32 (ScalAcc (i32 FPR32Op:$Rd),9873 (i32 (vector_extract9874 (v4i32 (int_aarch64_neon_sqdmull9875 (v4i16 V64:$Rn),9876 (v4i16 V64:$Rm))),9877 (i64 0))))),9878 (!cast<Instruction>(NAME # v1i32_indexed)9879 FPR32Op:$Rd,9880 (f16 (EXTRACT_SUBREG V64:$Rn, hsub)),9881 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rm, dsub),9882 (i64 0))>;9883 9884 def : Pat<(i32 (ScalAcc (i32 FPR32Op:$Rd),9885 (i32 (vector_extract9886 (v4i32 (int_aarch64_neon_sqdmull9887 (v4i16 V64:$Rn),9888 (dup_v8i16 (v8i16 V128_lo:$Rm),9889 VectorIndexH:$idx))),9890 (i64 0))))),9891 (!cast<Instruction>(NAME # v1i32_indexed)9892 FPR32Op:$Rd,9893 (f16 (EXTRACT_SUBREG V64:$Rn, hsub)),9894 V128_lo:$Rm,9895 VectorIndexH:$idx)>;9896 9897 def v1i64_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc,9898 FPR64Op, FPR32Op, V128, VectorIndexS,9899 asm, ".s", "", "", ".s",9900 [(set (i64 FPR64Op:$dst),9901 (ScalAcc (i64 FPR64Op:$Rd),9902 (i64 (int_aarch64_neon_sqdmulls_scalar9903 (i32 FPR32Op:$Rn),9904 (i32 (vector_extract (v4i32 V128:$Rm),9905 VectorIndexS:$idx))))))]> {9906 9907 bits<2> idx;9908 let Inst{11} = idx{1};9909 let Inst{21} = idx{0};9910 }9911}9912 9913multiclass SIMDVectorIndexedLongSD<bit U, bits<4> opc, string asm,9914 SDPatternOperator OpNode> {9915 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {9916 def v4i16_indexed : BaseSIMDIndexed<0, U, 0, 0b01, opc,9917 V128, V64,9918 V128_lo, VectorIndexH,9919 asm, ".4s", ".4s", ".4h", ".h",9920 [(set (v4i32 V128:$Rd),9921 (OpNode (v4i16 V64:$Rn),9922 (dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))]> {9923 bits<3> idx;9924 let Inst{11} = idx{2};9925 let Inst{21} = idx{1};9926 let Inst{20} = idx{0};9927 }9928 9929 def v8i16_indexed : BaseSIMDIndexed<1, U, 0, 0b01, opc,9930 V128, V128,9931 V128_lo, VectorIndexH,9932 asm#"2", ".4s", ".4s", ".8h", ".h",9933 [(set (v4i32 V128:$Rd),9934 (OpNode (extract_high_v8i16 (v8i16 V128:$Rn)),9935 (extract_high_dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))]> {9936 9937 bits<3> idx;9938 let Inst{11} = idx{2};9939 let Inst{21} = idx{1};9940 let Inst{20} = idx{0};9941 }9942 9943 def v2i32_indexed : BaseSIMDIndexed<0, U, 0, 0b10, opc,9944 V128, V64,9945 V128, VectorIndexS,9946 asm, ".2d", ".2d", ".2s", ".s",9947 [(set (v2i64 V128:$Rd),9948 (OpNode (v2i32 V64:$Rn),9949 (dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))]> {9950 bits<2> idx;9951 let Inst{11} = idx{1};9952 let Inst{21} = idx{0};9953 }9954 9955 def v4i32_indexed : BaseSIMDIndexed<1, U, 0, 0b10, opc,9956 V128, V128,9957 V128, VectorIndexS,9958 asm#"2", ".2d", ".2d", ".4s", ".s",9959 [(set (v2i64 V128:$Rd),9960 (OpNode (extract_high_v4i32 (v4i32 V128:$Rn)),9961 (extract_high_dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))]> {9962 bits<2> idx;9963 let Inst{11} = idx{1};9964 let Inst{21} = idx{0};9965 }9966 }9967}9968 9969multiclass SIMDVectorIndexedLongSDTied<bit U, bits<4> opc, string asm,9970 SDPatternOperator OpNode> {9971 let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in {9972 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc,9973 V128, V64,9974 V128_lo, VectorIndexH,9975 asm, ".4s", ".4s", ".4h", ".h",9976 [(set (v4i32 V128:$dst),9977 (OpNode (v4i32 V128:$Rd), (v4i16 V64:$Rn),9978 (dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))]> {9979 bits<3> idx;9980 let Inst{11} = idx{2};9981 let Inst{21} = idx{1};9982 let Inst{20} = idx{0};9983 }9984 9985 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,9986 V128, V128,9987 V128_lo, VectorIndexH,9988 asm#"2", ".4s", ".4s", ".8h", ".h",9989 [(set (v4i32 V128:$dst),9990 (OpNode (v4i32 V128:$Rd),9991 (extract_high_v8i16 (v8i16 V128:$Rn)),9992 (extract_high_dup_v8i16 (v8i16 V128_lo:$Rm), VectorIndexH:$idx)))]> {9993 bits<3> idx;9994 let Inst{11} = idx{2};9995 let Inst{21} = idx{1};9996 let Inst{20} = idx{0};9997 }9998 9999 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,10000 V128, V64,10001 V128, VectorIndexS,10002 asm, ".2d", ".2d", ".2s", ".s",10003 [(set (v2i64 V128:$dst),10004 (OpNode (v2i64 V128:$Rd), (v2i32 V64:$Rn),10005 (dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))]> {10006 bits<2> idx;10007 let Inst{11} = idx{1};10008 let Inst{21} = idx{0};10009 }10010 10011 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,10012 V128, V128,10013 V128, VectorIndexS,10014 asm#"2", ".2d", ".2d", ".4s", ".s",10015 [(set (v2i64 V128:$dst),10016 (OpNode (v2i64 V128:$Rd),10017 (extract_high_v4i32 (v4i32 V128:$Rn)),10018 (extract_high_dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx)))]> {10019 bits<2> idx;10020 let Inst{11} = idx{1};10021 let Inst{21} = idx{0};10022 }10023 }10024}10025 10026//----------------------------------------------------------------------------10027// AdvSIMD scalar shift by immediate10028//----------------------------------------------------------------------------10029 10030let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in10031class BaseSIMDScalarShift<bit U, bits<5> opc, bits<7> fixed_imm,10032 RegisterClass regtype1, RegisterClass regtype2,10033 Operand immtype, string asm, list<dag> pattern>10034 : I<(outs regtype1:$Rd), (ins regtype2:$Rn, immtype:$imm),10035 asm, "\t$Rd, $Rn, $imm", "", pattern>,10036 Sched<[WriteVd]> {10037 bits<5> Rd;10038 bits<5> Rn;10039 bits<7> imm;10040 let Inst{31-30} = 0b01;10041 let Inst{29} = U;10042 let Inst{28-23} = 0b111110;10043 let Inst{22-16} = fixed_imm;10044 let Inst{15-11} = opc;10045 let Inst{10} = 1;10046 let Inst{9-5} = Rn;10047 let Inst{4-0} = Rd;10048}10049 10050let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in10051class BaseSIMDScalarShiftTied<bit U, bits<5> opc, bits<7> fixed_imm,10052 RegisterClass regtype1, RegisterClass regtype2,10053 Operand immtype, string asm, list<dag> pattern>10054 : I<(outs regtype1:$dst), (ins regtype1:$Rd, regtype2:$Rn, immtype:$imm),10055 asm, "\t$Rd, $Rn, $imm", "$Rd = $dst", pattern>,10056 Sched<[WriteVd]> {10057 bits<5> Rd;10058 bits<5> Rn;10059 bits<7> imm;10060 let Inst{31-30} = 0b01;10061 let Inst{29} = U;10062 let Inst{28-23} = 0b111110;10063 let Inst{22-16} = fixed_imm;10064 let Inst{15-11} = opc;10065 let Inst{10} = 1;10066 let Inst{9-5} = Rn;10067 let Inst{4-0} = Rd;10068}10069 10070 10071multiclass SIMDFPScalarRShift<bit U, bits<5> opc, string asm> {10072 let Predicates = [HasNEON, HasFullFP16] in {10073 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},10074 FPR16, FPR16, vecshiftR16, asm, []> {10075 let Inst{19-16} = imm{3-0};10076 }10077 } // Predicates = [HasNEON, HasFullFP16]10078 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},10079 FPR32, FPR32, vecshiftR32, asm, []> {10080 let Inst{20-16} = imm{4-0};10081 }10082 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},10083 FPR64, FPR64, vecshiftR64, asm, []> {10084 let Inst{21-16} = imm{5-0};10085 }10086}10087 10088multiclass SIMDScalarRShiftD<bit U, bits<5> opc, string asm,10089 SDPatternOperator OpNode> {10090 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},10091 FPR64, FPR64, vecshiftR64, asm,10092 [(set (i64 FPR64:$Rd),10093 (OpNode (i64 FPR64:$Rn), (i32 vecshiftR64:$imm)))]> {10094 let Inst{21-16} = imm{5-0};10095 }10096 10097 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftR64:$imm))),10098 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftR64:$imm)>;10099}10100 10101multiclass SIMDScalarRShiftDTied<bit U, bits<5> opc, string asm,10102 SDPatternOperator OpNode = null_frag> {10103 def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?},10104 FPR64, FPR64, vecshiftR64, asm,10105 [(set (v1i64 FPR64:$dst), (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn),10106 (i32 vecshiftR64:$imm)))]> {10107 let Inst{21-16} = imm{5-0};10108 }10109}10110 10111multiclass SIMDScalarLShiftD<bit U, bits<5> opc, string asm,10112 SDPatternOperator OpNode> {10113 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},10114 FPR64, FPR64, vecshiftL64, asm,10115 [(set (i64 FPR64:$Rd),10116 (OpNode (i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> {10117 let Inst{21-16} = imm{5-0};10118 }10119 10120 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm))),10121 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftL64:$imm)>;10122}10123 10124let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in10125multiclass SIMDScalarLShiftDTied<bit U, bits<5> opc, string asm,10126 SDPatternOperator OpNode> {10127 def d : BaseSIMDScalarShiftTied<U, opc, {1,?,?,?,?,?,?},10128 FPR64, FPR64, vecshiftL64, asm,10129 [(set (v1i64 FPR64:$dst), (OpNode (v1i64 FPR64:$Rd), (v1i64 FPR64:$Rn),10130 (i32 vecshiftL64:$imm)))]> {10131 let Inst{21-16} = imm{5-0};10132 }10133}10134 10135let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in10136multiclass SIMDScalarRShiftBHS<bit U, bits<5> opc, string asm,10137 SDPatternOperator OpNode = null_frag> {10138 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?},10139 FPR8, FPR16, vecshiftR8, asm, []> {10140 let Inst{18-16} = imm{2-0};10141 }10142 10143 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},10144 FPR16, FPR32, vecshiftR16, asm, []> {10145 let Inst{19-16} = imm{3-0};10146 }10147 10148 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},10149 FPR32, FPR64, vecshiftR32, asm,10150 [(set (i32 FPR32:$Rd), (OpNode (i64 FPR64:$Rn), vecshiftR32:$imm))]> {10151 let Inst{20-16} = imm{4-0};10152 }10153}10154 10155multiclass SIMDScalarLShiftBHSD<bit U, bits<5> opc, string asm,10156 SDPatternOperator OpNode> {10157 def b : BaseSIMDScalarShift<U, opc, {0,0,0,1,?,?,?},10158 FPR8, FPR8, vecshiftL8, asm, []> {10159 let Inst{18-16} = imm{2-0};10160 }10161 10162 def h : BaseSIMDScalarShift<U, opc, {0,0,1,?,?,?,?},10163 FPR16, FPR16, vecshiftL16, asm, []> {10164 let Inst{19-16} = imm{3-0};10165 }10166 10167 def s : BaseSIMDScalarShift<U, opc, {0,1,?,?,?,?,?},10168 FPR32, FPR32, vecshiftL32, asm,10169 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn), (i32 vecshiftL32:$imm)))]> {10170 let Inst{20-16} = imm{4-0};10171 }10172 10173 def d : BaseSIMDScalarShift<U, opc, {1,?,?,?,?,?,?},10174 FPR64, FPR64, vecshiftL64, asm,10175 [(set (i64 FPR64:$Rd), (OpNode (i64 FPR64:$Rn), (i32 vecshiftL64:$imm)))]> {10176 let Inst{21-16} = imm{5-0};10177 }10178 10179 def : Pat<(v1i64 (OpNode (v1i64 FPR64:$Rn), (i32 vecshiftL64:$imm))),10180 (!cast<Instruction>(NAME # "d") FPR64:$Rn, vecshiftL64:$imm)>;10181}10182 10183//----------------------------------------------------------------------------10184// AdvSIMD vector x indexed element10185//----------------------------------------------------------------------------10186 10187let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in10188class BaseSIMDVectorShift<bit Q, bit U, bits<5> opc, bits<7> fixed_imm,10189 RegisterOperand dst_reg, RegisterOperand src_reg,10190 Operand immtype,10191 string asm, string dst_kind, string src_kind,10192 list<dag> pattern>10193 : I<(outs dst_reg:$Rd), (ins src_reg:$Rn, immtype:$imm),10194 asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" #10195 "|" # dst_kind # "\t$Rd, $Rn, $imm}", "", pattern>,10196 Sched<[!if(Q, WriteVq, WriteVd)]> {10197 bits<5> Rd;10198 bits<5> Rn;10199 let Inst{31} = 0;10200 let Inst{30} = Q;10201 let Inst{29} = U;10202 let Inst{28-23} = 0b011110;10203 let Inst{22-16} = fixed_imm;10204 let Inst{15-11} = opc;10205 let Inst{10} = 1;10206 let Inst{9-5} = Rn;10207 let Inst{4-0} = Rd;10208}10209 10210let mayStore = 0, mayLoad = 0, hasSideEffects = 0 in10211class BaseSIMDVectorShiftTied<bit Q, bit U, bits<5> opc, bits<7> fixed_imm,10212 RegisterOperand vectype1, RegisterOperand vectype2,10213 Operand immtype,10214 string asm, string dst_kind, string src_kind,10215 list<dag> pattern>10216 : I<(outs vectype1:$dst), (ins vectype1:$Rd, vectype2:$Rn, immtype:$imm),10217 asm, "{\t$Rd" # dst_kind # ", $Rn" # src_kind # ", $imm" #10218 "|" # dst_kind # "\t$Rd, $Rn, $imm}", "$Rd = $dst", pattern>,10219 Sched<[!if(Q, WriteVq, WriteVd)]> {10220 bits<5> Rd;10221 bits<5> Rn;10222 let Inst{31} = 0;10223 let Inst{30} = Q;10224 let Inst{29} = U;10225 let Inst{28-23} = 0b011110;10226 let Inst{22-16} = fixed_imm;10227 let Inst{15-11} = opc;10228 let Inst{10} = 1;10229 let Inst{9-5} = Rn;10230 let Inst{4-0} = Rd;10231}10232 10233multiclass SIMDVectorRShiftSD<bit U, bits<5> opc, string asm,10234 Intrinsic OpNode> {10235 let Predicates = [HasNEON, HasFullFP16] in {10236 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},10237 V64, V64, vecshiftR16,10238 asm, ".4h", ".4h",10239 [(set (v4i16 V64:$Rd), (OpNode (v4f16 V64:$Rn), (i32 vecshiftR16:$imm)))]> {10240 bits<4> imm;10241 let Inst{19-16} = imm;10242 }10243 10244 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},10245 V128, V128, vecshiftR16,10246 asm, ".8h", ".8h",10247 [(set (v8i16 V128:$Rd), (OpNode (v8f16 V128:$Rn), (i32 vecshiftR16:$imm)))]> {10248 bits<4> imm;10249 let Inst{19-16} = imm;10250 }10251 } // Predicates = [HasNEON, HasFullFP16]10252 10253 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},10254 V64, V64, vecshiftR32,10255 asm, ".2s", ".2s",10256 [(set (v2i32 V64:$Rd), (OpNode (v2f32 V64:$Rn), (i32 vecshiftR32:$imm)))]> {10257 bits<5> imm;10258 let Inst{20-16} = imm;10259 }10260 10261 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},10262 V128, V128, vecshiftR32,10263 asm, ".4s", ".4s",10264 [(set (v4i32 V128:$Rd), (OpNode (v4f32 V128:$Rn), (i32 vecshiftR32:$imm)))]> {10265 bits<5> imm;10266 let Inst{20-16} = imm;10267 }10268 10269 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},10270 V128, V128, vecshiftR64,10271 asm, ".2d", ".2d",10272 [(set (v2i64 V128:$Rd), (OpNode (v2f64 V128:$Rn), (i32 vecshiftR64:$imm)))]> {10273 bits<6> imm;10274 let Inst{21-16} = imm;10275 }10276}10277 10278multiclass SIMDVectorRShiftToFP<bit U, bits<5> opc, string asm,10279 Intrinsic OpNode> {10280 let Predicates = [HasNEON, HasFullFP16] in {10281 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},10282 V64, V64, vecshiftR16,10283 asm, ".4h", ".4h",10284 [(set (v4f16 V64:$Rd), (OpNode (v4i16 V64:$Rn), (i32 vecshiftR16:$imm)))]> {10285 bits<4> imm;10286 let Inst{19-16} = imm;10287 }10288 10289 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},10290 V128, V128, vecshiftR16,10291 asm, ".8h", ".8h",10292 [(set (v8f16 V128:$Rd), (OpNode (v8i16 V128:$Rn), (i32 vecshiftR16:$imm)))]> {10293 bits<4> imm;10294 let Inst{19-16} = imm;10295 }10296 } // Predicates = [HasNEON, HasFullFP16]10297 10298 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},10299 V64, V64, vecshiftR32,10300 asm, ".2s", ".2s",10301 [(set (v2f32 V64:$Rd), (OpNode (v2i32 V64:$Rn), (i32 vecshiftR32:$imm)))]> {10302 bits<5> imm;10303 let Inst{20-16} = imm;10304 }10305 10306 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},10307 V128, V128, vecshiftR32,10308 asm, ".4s", ".4s",10309 [(set (v4f32 V128:$Rd), (OpNode (v4i32 V128:$Rn), (i32 vecshiftR32:$imm)))]> {10310 bits<5> imm;10311 let Inst{20-16} = imm;10312 }10313 10314 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},10315 V128, V128, vecshiftR64,10316 asm, ".2d", ".2d",10317 [(set (v2f64 V128:$Rd), (OpNode (v2i64 V128:$Rn), (i32 vecshiftR64:$imm)))]> {10318 bits<6> imm;10319 let Inst{21-16} = imm;10320 }10321}10322 10323multiclass SIMDVectorRShiftNarrowBHS<bit U, bits<5> opc, string asm,10324 SDPatternOperator OpNode> {10325 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},10326 V64, V128, vecshiftR16Narrow,10327 asm, ".8b", ".8h",10328 [(set (v8i8 V64:$Rd), (OpNode (v8i16 V128:$Rn), vecshiftR16Narrow:$imm))]> {10329 bits<3> imm;10330 let Inst{18-16} = imm;10331 }10332 10333 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?},10334 V128, V128, vecshiftR16Narrow,10335 asm#"2", ".16b", ".8h", []> {10336 bits<3> imm;10337 let Inst{18-16} = imm;10338 let hasSideEffects = 0;10339 }10340 10341 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},10342 V64, V128, vecshiftR32Narrow,10343 asm, ".4h", ".4s",10344 [(set (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn), vecshiftR32Narrow:$imm))]> {10345 bits<4> imm;10346 let Inst{19-16} = imm;10347 }10348 10349 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?},10350 V128, V128, vecshiftR32Narrow,10351 asm#"2", ".8h", ".4s", []> {10352 bits<4> imm;10353 let Inst{19-16} = imm;10354 let hasSideEffects = 0;10355 }10356 10357 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},10358 V64, V128, vecshiftR64Narrow,10359 asm, ".2s", ".2d",10360 [(set (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn), vecshiftR64Narrow:$imm))]> {10361 bits<5> imm;10362 let Inst{20-16} = imm;10363 }10364 10365 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?},10366 V128, V128, vecshiftR64Narrow,10367 asm#"2", ".4s", ".2d", []> {10368 bits<5> imm;10369 let Inst{20-16} = imm;10370 let hasSideEffects = 0;10371 }10372 10373 // TableGen doesn't like patters w/ INSERT_SUBREG on the instructions10374 // themselves, so put them here instead.10375 10376 // Patterns involving what's effectively an insert high and a normal10377 // intrinsic, represented by CONCAT_VECTORS.10378 def : Pat<(concat_vectors (v8i8 V64:$Rd),(OpNode (v8i16 V128:$Rn),10379 vecshiftR16Narrow:$imm)),10380 (!cast<Instruction>(NAME # "v16i8_shift")10381 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),10382 V128:$Rn, vecshiftR16Narrow:$imm)>;10383 def : Pat<(concat_vectors (v4i16 V64:$Rd), (OpNode (v4i32 V128:$Rn),10384 vecshiftR32Narrow:$imm)),10385 (!cast<Instruction>(NAME # "v8i16_shift")10386 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),10387 V128:$Rn, vecshiftR32Narrow:$imm)>;10388 def : Pat<(concat_vectors (v2i32 V64:$Rd), (OpNode (v2i64 V128:$Rn),10389 vecshiftR64Narrow:$imm)),10390 (!cast<Instruction>(NAME # "v4i32_shift")10391 (INSERT_SUBREG (IMPLICIT_DEF), V64:$Rd, dsub),10392 V128:$Rn, vecshiftR64Narrow:$imm)>;10393}10394 10395multiclass SIMDVectorLShiftBHSD<bit U, bits<5> opc, string asm,10396 SDPatternOperator OpNode> {10397 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},10398 V64, V64, vecshiftL8,10399 asm, ".8b", ".8b",10400 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn),10401 (i32 vecshiftL8:$imm)))]> {10402 bits<3> imm;10403 let Inst{18-16} = imm;10404 }10405 10406 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?},10407 V128, V128, vecshiftL8,10408 asm, ".16b", ".16b",10409 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn),10410 (i32 vecshiftL8:$imm)))]> {10411 bits<3> imm;10412 let Inst{18-16} = imm;10413 }10414 10415 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},10416 V64, V64, vecshiftL16,10417 asm, ".4h", ".4h",10418 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn),10419 (i32 vecshiftL16:$imm)))]> {10420 bits<4> imm;10421 let Inst{19-16} = imm;10422 }10423 10424 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},10425 V128, V128, vecshiftL16,10426 asm, ".8h", ".8h",10427 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn),10428 (i32 vecshiftL16:$imm)))]> {10429 bits<4> imm;10430 let Inst{19-16} = imm;10431 }10432 10433 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},10434 V64, V64, vecshiftL32,10435 asm, ".2s", ".2s",10436 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn),10437 (i32 vecshiftL32:$imm)))]> {10438 bits<5> imm;10439 let Inst{20-16} = imm;10440 }10441 10442 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},10443 V128, V128, vecshiftL32,10444 asm, ".4s", ".4s",10445 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn),10446 (i32 vecshiftL32:$imm)))]> {10447 bits<5> imm;10448 let Inst{20-16} = imm;10449 }10450 10451 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},10452 V128, V128, vecshiftL64,10453 asm, ".2d", ".2d",10454 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn),10455 (i32 vecshiftL64:$imm)))]> {10456 bits<6> imm;10457 let Inst{21-16} = imm;10458 }10459}10460 10461multiclass SIMDVectorRShiftBHSD<bit U, bits<5> opc, string asm,10462 SDPatternOperator OpNode> {10463 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},10464 V64, V64, vecshiftR8,10465 asm, ".8b", ".8b",10466 [(set (v8i8 V64:$Rd), (OpNode (v8i8 V64:$Rn),10467 (i32 vecshiftR8:$imm)))]> {10468 bits<3> imm;10469 let Inst{18-16} = imm;10470 }10471 10472 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?},10473 V128, V128, vecshiftR8,10474 asm, ".16b", ".16b",10475 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn),10476 (i32 vecshiftR8:$imm)))]> {10477 bits<3> imm;10478 let Inst{18-16} = imm;10479 }10480 10481 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},10482 V64, V64, vecshiftR16,10483 asm, ".4h", ".4h",10484 [(set (v4i16 V64:$Rd), (OpNode (v4i16 V64:$Rn),10485 (i32 vecshiftR16:$imm)))]> {10486 bits<4> imm;10487 let Inst{19-16} = imm;10488 }10489 10490 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},10491 V128, V128, vecshiftR16,10492 asm, ".8h", ".8h",10493 [(set (v8i16 V128:$Rd), (OpNode (v8i16 V128:$Rn),10494 (i32 vecshiftR16:$imm)))]> {10495 bits<4> imm;10496 let Inst{19-16} = imm;10497 }10498 10499 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},10500 V64, V64, vecshiftR32,10501 asm, ".2s", ".2s",10502 [(set (v2i32 V64:$Rd), (OpNode (v2i32 V64:$Rn),10503 (i32 vecshiftR32:$imm)))]> {10504 bits<5> imm;10505 let Inst{20-16} = imm;10506 }10507 10508 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},10509 V128, V128, vecshiftR32,10510 asm, ".4s", ".4s",10511 [(set (v4i32 V128:$Rd), (OpNode (v4i32 V128:$Rn),10512 (i32 vecshiftR32:$imm)))]> {10513 bits<5> imm;10514 let Inst{20-16} = imm;10515 }10516 10517 def v2i64_shift : BaseSIMDVectorShift<1, U, opc, {1,?,?,?,?,?,?},10518 V128, V128, vecshiftR64,10519 asm, ".2d", ".2d",10520 [(set (v2i64 V128:$Rd), (OpNode (v2i64 V128:$Rn),10521 (i32 vecshiftR64:$imm)))]> {10522 bits<6> imm;10523 let Inst{21-16} = imm;10524 }10525}10526 10527let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in10528multiclass SIMDVectorRShiftBHSDTied<bit U, bits<5> opc, string asm,10529 SDPatternOperator OpNode = null_frag> {10530 def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?},10531 V64, V64, vecshiftR8, asm, ".8b", ".8b",10532 [(set (v8i8 V64:$dst),10533 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn),10534 (i32 vecshiftR8:$imm)))]> {10535 bits<3> imm;10536 let Inst{18-16} = imm;10537 }10538 10539 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?},10540 V128, V128, vecshiftR8, asm, ".16b", ".16b",10541 [(set (v16i8 V128:$dst),10542 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),10543 (i32 vecshiftR8:$imm)))]> {10544 bits<3> imm;10545 let Inst{18-16} = imm;10546 }10547 10548 def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?},10549 V64, V64, vecshiftR16, asm, ".4h", ".4h",10550 [(set (v4i16 V64:$dst),10551 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn),10552 (i32 vecshiftR16:$imm)))]> {10553 bits<4> imm;10554 let Inst{19-16} = imm;10555 }10556 10557 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?},10558 V128, V128, vecshiftR16, asm, ".8h", ".8h",10559 [(set (v8i16 V128:$dst),10560 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn),10561 (i32 vecshiftR16:$imm)))]> {10562 bits<4> imm;10563 let Inst{19-16} = imm;10564 }10565 10566 def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?},10567 V64, V64, vecshiftR32, asm, ".2s", ".2s",10568 [(set (v2i32 V64:$dst),10569 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn),10570 (i32 vecshiftR32:$imm)))]> {10571 bits<5> imm;10572 let Inst{20-16} = imm;10573 }10574 10575 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?},10576 V128, V128, vecshiftR32, asm, ".4s", ".4s",10577 [(set (v4i32 V128:$dst),10578 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),10579 (i32 vecshiftR32:$imm)))]> {10580 bits<5> imm;10581 let Inst{20-16} = imm;10582 }10583 10584 def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?},10585 V128, V128, vecshiftR64,10586 asm, ".2d", ".2d", [(set (v2i64 V128:$dst),10587 (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn),10588 (i32 vecshiftR64:$imm)))]> {10589 bits<6> imm;10590 let Inst{21-16} = imm;10591 }10592}10593 10594multiclass SIMDVectorLShiftBHSDTied<bit U, bits<5> opc, string asm,10595 SDPatternOperator OpNode = null_frag> {10596 def v8i8_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,0,1,?,?,?},10597 V64, V64, vecshiftL8,10598 asm, ".8b", ".8b",10599 [(set (v8i8 V64:$dst),10600 (OpNode (v8i8 V64:$Rd), (v8i8 V64:$Rn),10601 (i32 vecshiftL8:$imm)))]> {10602 bits<3> imm;10603 let Inst{18-16} = imm;10604 }10605 10606 def v16i8_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,0,1,?,?,?},10607 V128, V128, vecshiftL8,10608 asm, ".16b", ".16b",10609 [(set (v16i8 V128:$dst),10610 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn),10611 (i32 vecshiftL8:$imm)))]> {10612 bits<3> imm;10613 let Inst{18-16} = imm;10614 }10615 10616 def v4i16_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,0,1,?,?,?,?},10617 V64, V64, vecshiftL16,10618 asm, ".4h", ".4h",10619 [(set (v4i16 V64:$dst),10620 (OpNode (v4i16 V64:$Rd), (v4i16 V64:$Rn),10621 (i32 vecshiftL16:$imm)))]> {10622 bits<4> imm;10623 let Inst{19-16} = imm;10624 }10625 10626 def v8i16_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,0,1,?,?,?,?},10627 V128, V128, vecshiftL16,10628 asm, ".8h", ".8h",10629 [(set (v8i16 V128:$dst),10630 (OpNode (v8i16 V128:$Rd), (v8i16 V128:$Rn),10631 (i32 vecshiftL16:$imm)))]> {10632 bits<4> imm;10633 let Inst{19-16} = imm;10634 }10635 10636 def v2i32_shift : BaseSIMDVectorShiftTied<0, U, opc, {0,1,?,?,?,?,?},10637 V64, V64, vecshiftL32,10638 asm, ".2s", ".2s",10639 [(set (v2i32 V64:$dst),10640 (OpNode (v2i32 V64:$Rd), (v2i32 V64:$Rn),10641 (i32 vecshiftL32:$imm)))]> {10642 bits<5> imm;10643 let Inst{20-16} = imm;10644 }10645 10646 def v4i32_shift : BaseSIMDVectorShiftTied<1, U, opc, {0,1,?,?,?,?,?},10647 V128, V128, vecshiftL32,10648 asm, ".4s", ".4s",10649 [(set (v4i32 V128:$dst),10650 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),10651 (i32 vecshiftL32:$imm)))]> {10652 bits<5> imm;10653 let Inst{20-16} = imm;10654 }10655 10656 def v2i64_shift : BaseSIMDVectorShiftTied<1, U, opc, {1,?,?,?,?,?,?},10657 V128, V128, vecshiftL64,10658 asm, ".2d", ".2d",10659 [(set (v2i64 V128:$dst),10660 (OpNode (v2i64 V128:$Rd), (v2i64 V128:$Rn),10661 (i32 vecshiftL64:$imm)))]> {10662 bits<6> imm;10663 let Inst{21-16} = imm;10664 }10665}10666 10667multiclass SIMDVectorLShiftLongBHSD<bit U, bits<5> opc, string asm,10668 SDPatternOperator OpNode> {10669 def v8i8_shift : BaseSIMDVectorShift<0, U, opc, {0,0,0,1,?,?,?},10670 V128, V64, vecshiftL8, asm, ".8h", ".8b",10671 [(set (v8i16 V128:$Rd), (OpNode (v8i8 V64:$Rn), vecshiftL8:$imm))]> {10672 bits<3> imm;10673 let Inst{18-16} = imm;10674 }10675 10676 def v16i8_shift : BaseSIMDVectorShift<1, U, opc, {0,0,0,1,?,?,?},10677 V128, V128, vecshiftL8,10678 asm#"2", ".8h", ".16b",10679 [(set (v8i16 V128:$Rd),10680 (OpNode (extract_high_v16i8 (v16i8 V128:$Rn)), vecshiftL8:$imm))]> {10681 bits<3> imm;10682 let Inst{18-16} = imm;10683 }10684 10685 def v4i16_shift : BaseSIMDVectorShift<0, U, opc, {0,0,1,?,?,?,?},10686 V128, V64, vecshiftL16, asm, ".4s", ".4h",10687 [(set (v4i32 V128:$Rd), (OpNode (v4i16 V64:$Rn), vecshiftL16:$imm))]> {10688 bits<4> imm;10689 let Inst{19-16} = imm;10690 }10691 10692 def v8i16_shift : BaseSIMDVectorShift<1, U, opc, {0,0,1,?,?,?,?},10693 V128, V128, vecshiftL16,10694 asm#"2", ".4s", ".8h",10695 [(set (v4i32 V128:$Rd),10696 (OpNode (extract_high_v8i16 (v8i16 V128:$Rn)), vecshiftL16:$imm))]> {10697 10698 bits<4> imm;10699 let Inst{19-16} = imm;10700 }10701 10702 def v2i32_shift : BaseSIMDVectorShift<0, U, opc, {0,1,?,?,?,?,?},10703 V128, V64, vecshiftL32, asm, ".2d", ".2s",10704 [(set (v2i64 V128:$Rd), (OpNode (v2i32 V64:$Rn), vecshiftL32:$imm))]> {10705 bits<5> imm;10706 let Inst{20-16} = imm;10707 }10708 10709 def v4i32_shift : BaseSIMDVectorShift<1, U, opc, {0,1,?,?,?,?,?},10710 V128, V128, vecshiftL32,10711 asm#"2", ".2d", ".4s",10712 [(set (v2i64 V128:$Rd),10713 (OpNode (extract_high_v4i32 (v4i32 V128:$Rn)), vecshiftL32:$imm))]> {10714 bits<5> imm;10715 let Inst{20-16} = imm;10716 }10717}10718 10719 10720//---10721// Vector load/store10722//---10723// SIMD ldX/stX no-index memory references don't allow the optional10724// ", #0" constant and handle post-indexing explicitly, so we use10725// a more specialized parse method for them. Otherwise, it's the same as10726// the general GPR64sp handling.10727 10728class BaseSIMDLdSt<bit Q, bit L, bits<4> opcode, bits<2> size,10729 string asm, dag oops, dag iops, list<dag> pattern>10730 : I<oops, iops, asm, "\t$Vt, [$Rn]", "", pattern> {10731 bits<5> Vt;10732 bits<5> Rn;10733 let Inst{31} = 0;10734 let Inst{30} = Q;10735 let Inst{29-23} = 0b0011000;10736 let Inst{22} = L;10737 let Inst{21-16} = 0b000000;10738 let Inst{15-12} = opcode;10739 let Inst{11-10} = size;10740 let Inst{9-5} = Rn;10741 let Inst{4-0} = Vt;10742}10743 10744class BaseSIMDLdStPost<bit Q, bit L, bits<4> opcode, bits<2> size,10745 string asm, dag oops, dag iops>10746 : I<oops, iops, asm, "\t$Vt, [$Rn], $Xm", "$Rn = $wback", []> {10747 bits<5> Vt;10748 bits<5> Rn;10749 bits<5> Xm;10750 let Inst{31} = 0;10751 let Inst{30} = Q;10752 let Inst{29-23} = 0b0011001;10753 let Inst{22} = L;10754 let Inst{21} = 0;10755 let Inst{20-16} = Xm;10756 let Inst{15-12} = opcode;10757 let Inst{11-10} = size;10758 let Inst{9-5} = Rn;10759 let Inst{4-0} = Vt;10760}10761 10762// The immediate form of AdvSIMD post-indexed addressing is encoded with10763// register post-index addressing from the zero register.10764multiclass SIMDLdStAliases<string BaseName, string asm, string layout, string Count,10765 int Offset, int Size> {10766 // E.g. "ld1 { v0.8b, v1.8b }, [x1], #16"10767 // "ld1\t$Vt, [$Rn], #16"10768 // may get mapped to10769 // (LD1Twov8b_POST VecListTwo8b:$Vt, GPR64sp:$Rn, XZR)10770 def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset,10771 (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST")10772 GPR64sp:$Rn,10773 !cast<RegisterOperand>("VecList" # Count # layout):$Vt,10774 XZR), 1>;10775 10776 // E.g. "ld1.8b { v0, v1 }, [x1], #16"10777 // "ld1.8b\t$Vt, [$Rn], #16"10778 // may get mapped to10779 // (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, XZR)10780 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset,10781 (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST")10782 GPR64sp:$Rn,10783 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,10784 XZR), 0>;10785 10786 // E.g. "ld1.8b { v0, v1 }, [x1]"10787 // "ld1\t$Vt, [$Rn]"10788 // may get mapped to10789 // (LD1Twov8b VecListTwo64:$Vt, GPR64sp:$Rn)10790 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]",10791 (!cast<Instruction>(BaseName # Count # "v" # layout)10792 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,10793 GPR64sp:$Rn), 0>;10794 10795 // E.g. "ld1.8b { v0, v1 }, [x1], x2"10796 // "ld1\t$Vt, [$Rn], $Xm"10797 // may get mapped to10798 // (LD1Twov8b_POST VecListTwo64:$Vt, GPR64sp:$Rn, GPR64pi8:$Xm)10799 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm",10800 (!cast<Instruction>(BaseName # Count # "v" # layout # "_POST")10801 GPR64sp:$Rn,10802 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,10803 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>;10804}10805 10806multiclass BaseSIMDLdN<string BaseName, string Count, string asm, string veclist,10807 int Offset128, int Offset64, bits<4> opcode> {10808 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {10809 def v16b: BaseSIMDLdSt<1, 1, opcode, 0b00, asm,10810 (outs !cast<RegisterOperand>(veclist # "16b"):$Vt),10811 (ins GPR64sp:$Rn), []>;10812 def v8h : BaseSIMDLdSt<1, 1, opcode, 0b01, asm,10813 (outs !cast<RegisterOperand>(veclist # "8h"):$Vt),10814 (ins GPR64sp:$Rn), []>;10815 def v4s : BaseSIMDLdSt<1, 1, opcode, 0b10, asm,10816 (outs !cast<RegisterOperand>(veclist # "4s"):$Vt),10817 (ins GPR64sp:$Rn), []>;10818 def v2d : BaseSIMDLdSt<1, 1, opcode, 0b11, asm,10819 (outs !cast<RegisterOperand>(veclist # "2d"):$Vt),10820 (ins GPR64sp:$Rn), []>;10821 def v8b : BaseSIMDLdSt<0, 1, opcode, 0b00, asm,10822 (outs !cast<RegisterOperand>(veclist # "8b"):$Vt),10823 (ins GPR64sp:$Rn), []>;10824 def v4h : BaseSIMDLdSt<0, 1, opcode, 0b01, asm,10825 (outs !cast<RegisterOperand>(veclist # "4h"):$Vt),10826 (ins GPR64sp:$Rn), []>;10827 def v2s : BaseSIMDLdSt<0, 1, opcode, 0b10, asm,10828 (outs !cast<RegisterOperand>(veclist # "2s"):$Vt),10829 (ins GPR64sp:$Rn), []>;10830 10831 10832 def v16b_POST: BaseSIMDLdStPost<1, 1, opcode, 0b00, asm,10833 (outs GPR64sp:$wback,10834 !cast<RegisterOperand>(veclist # "16b"):$Vt),10835 (ins GPR64sp:$Rn,10836 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;10837 def v8h_POST : BaseSIMDLdStPost<1, 1, opcode, 0b01, asm,10838 (outs GPR64sp:$wback,10839 !cast<RegisterOperand>(veclist # "8h"):$Vt),10840 (ins GPR64sp:$Rn,10841 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;10842 def v4s_POST : BaseSIMDLdStPost<1, 1, opcode, 0b10, asm,10843 (outs GPR64sp:$wback,10844 !cast<RegisterOperand>(veclist # "4s"):$Vt),10845 (ins GPR64sp:$Rn,10846 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;10847 def v2d_POST : BaseSIMDLdStPost<1, 1, opcode, 0b11, asm,10848 (outs GPR64sp:$wback,10849 !cast<RegisterOperand>(veclist # "2d"):$Vt),10850 (ins GPR64sp:$Rn,10851 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;10852 def v8b_POST : BaseSIMDLdStPost<0, 1, opcode, 0b00, asm,10853 (outs GPR64sp:$wback,10854 !cast<RegisterOperand>(veclist # "8b"):$Vt),10855 (ins GPR64sp:$Rn,10856 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;10857 def v4h_POST : BaseSIMDLdStPost<0, 1, opcode, 0b01, asm,10858 (outs GPR64sp:$wback,10859 !cast<RegisterOperand>(veclist # "4h"):$Vt),10860 (ins GPR64sp:$Rn,10861 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;10862 def v2s_POST : BaseSIMDLdStPost<0, 1, opcode, 0b10, asm,10863 (outs GPR64sp:$wback,10864 !cast<RegisterOperand>(veclist # "2s"):$Vt),10865 (ins GPR64sp:$Rn,10866 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;10867 }10868 10869 defm : SIMDLdStAliases<BaseName, asm, "16b", Count, Offset128, 128>;10870 defm : SIMDLdStAliases<BaseName, asm, "8h", Count, Offset128, 128>;10871 defm : SIMDLdStAliases<BaseName, asm, "4s", Count, Offset128, 128>;10872 defm : SIMDLdStAliases<BaseName, asm, "2d", Count, Offset128, 128>;10873 defm : SIMDLdStAliases<BaseName, asm, "8b", Count, Offset64, 64>;10874 defm : SIMDLdStAliases<BaseName, asm, "4h", Count, Offset64, 64>;10875 defm : SIMDLdStAliases<BaseName, asm, "2s", Count, Offset64, 64>;10876}10877 10878// Only ld1/st1 has a v1d version.10879multiclass BaseSIMDStN<string BaseName, string Count, string asm, string veclist,10880 int Offset128, int Offset64, bits<4> opcode> {10881 let hasSideEffects = 0, mayStore = 1, mayLoad = 0 in {10882 def v16b : BaseSIMDLdSt<1, 0, opcode, 0b00, asm, (outs),10883 (ins !cast<RegisterOperand>(veclist # "16b"):$Vt,10884 GPR64sp:$Rn), []>;10885 def v8h : BaseSIMDLdSt<1, 0, opcode, 0b01, asm, (outs),10886 (ins !cast<RegisterOperand>(veclist # "8h"):$Vt,10887 GPR64sp:$Rn), []>;10888 def v4s : BaseSIMDLdSt<1, 0, opcode, 0b10, asm, (outs),10889 (ins !cast<RegisterOperand>(veclist # "4s"):$Vt,10890 GPR64sp:$Rn), []>;10891 def v2d : BaseSIMDLdSt<1, 0, opcode, 0b11, asm, (outs),10892 (ins !cast<RegisterOperand>(veclist # "2d"):$Vt,10893 GPR64sp:$Rn), []>;10894 def v8b : BaseSIMDLdSt<0, 0, opcode, 0b00, asm, (outs),10895 (ins !cast<RegisterOperand>(veclist # "8b"):$Vt,10896 GPR64sp:$Rn), []>;10897 def v4h : BaseSIMDLdSt<0, 0, opcode, 0b01, asm, (outs),10898 (ins !cast<RegisterOperand>(veclist # "4h"):$Vt,10899 GPR64sp:$Rn), []>;10900 def v2s : BaseSIMDLdSt<0, 0, opcode, 0b10, asm, (outs),10901 (ins !cast<RegisterOperand>(veclist # "2s"):$Vt,10902 GPR64sp:$Rn), []>;10903 10904 def v16b_POST : BaseSIMDLdStPost<1, 0, opcode, 0b00, asm,10905 (outs GPR64sp:$wback),10906 (ins !cast<RegisterOperand>(veclist # "16b"):$Vt,10907 GPR64sp:$Rn,10908 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;10909 def v8h_POST : BaseSIMDLdStPost<1, 0, opcode, 0b01, asm,10910 (outs GPR64sp:$wback),10911 (ins !cast<RegisterOperand>(veclist # "8h"):$Vt,10912 GPR64sp:$Rn,10913 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;10914 def v4s_POST : BaseSIMDLdStPost<1, 0, opcode, 0b10, asm,10915 (outs GPR64sp:$wback),10916 (ins !cast<RegisterOperand>(veclist # "4s"):$Vt,10917 GPR64sp:$Rn,10918 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;10919 def v2d_POST : BaseSIMDLdStPost<1, 0, opcode, 0b11, asm,10920 (outs GPR64sp:$wback),10921 (ins !cast<RegisterOperand>(veclist # "2d"):$Vt,10922 GPR64sp:$Rn,10923 !cast<RegisterOperand>("GPR64pi" # Offset128):$Xm)>;10924 def v8b_POST : BaseSIMDLdStPost<0, 0, opcode, 0b00, asm,10925 (outs GPR64sp:$wback),10926 (ins !cast<RegisterOperand>(veclist # "8b"):$Vt,10927 GPR64sp:$Rn,10928 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;10929 def v4h_POST : BaseSIMDLdStPost<0, 0, opcode, 0b01, asm,10930 (outs GPR64sp:$wback),10931 (ins !cast<RegisterOperand>(veclist # "4h"):$Vt,10932 GPR64sp:$Rn,10933 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;10934 def v2s_POST : BaseSIMDLdStPost<0, 0, opcode, 0b10, asm,10935 (outs GPR64sp:$wback),10936 (ins !cast<RegisterOperand>(veclist # "2s"):$Vt,10937 GPR64sp:$Rn,10938 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;10939 }10940 10941 defm : SIMDLdStAliases<BaseName, asm, "16b", Count, Offset128, 128>;10942 defm : SIMDLdStAliases<BaseName, asm, "8h", Count, Offset128, 128>;10943 defm : SIMDLdStAliases<BaseName, asm, "4s", Count, Offset128, 128>;10944 defm : SIMDLdStAliases<BaseName, asm, "2d", Count, Offset128, 128>;10945 defm : SIMDLdStAliases<BaseName, asm, "8b", Count, Offset64, 64>;10946 defm : SIMDLdStAliases<BaseName, asm, "4h", Count, Offset64, 64>;10947 defm : SIMDLdStAliases<BaseName, asm, "2s", Count, Offset64, 64>;10948}10949 10950multiclass BaseSIMDLd1<string BaseName, string Count, string asm, string veclist,10951 int Offset128, int Offset64, bits<4> opcode>10952 : BaseSIMDLdN<BaseName, Count, asm, veclist, Offset128, Offset64, opcode> {10953 10954 // LD1 instructions have extra "1d" variants.10955 let hasSideEffects = 0, mayLoad = 1, mayStore = 0 in {10956 def v1d : BaseSIMDLdSt<0, 1, opcode, 0b11, asm,10957 (outs !cast<RegisterOperand>(veclist # "1d"):$Vt),10958 (ins GPR64sp:$Rn), []>;10959 10960 def v1d_POST : BaseSIMDLdStPost<0, 1, opcode, 0b11, asm,10961 (outs GPR64sp:$wback,10962 !cast<RegisterOperand>(veclist # "1d"):$Vt),10963 (ins GPR64sp:$Rn,10964 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;10965 }10966 10967 defm : SIMDLdStAliases<BaseName, asm, "1d", Count, Offset64, 64>;10968}10969 10970multiclass BaseSIMDSt1<string BaseName, string Count, string asm, string veclist,10971 int Offset128, int Offset64, bits<4> opcode>10972 : BaseSIMDStN<BaseName, Count, asm, veclist, Offset128, Offset64, opcode> {10973 10974 // ST1 instructions have extra "1d" variants.10975 let hasSideEffects = 0, mayLoad = 0, mayStore = 1 in {10976 def v1d : BaseSIMDLdSt<0, 0, opcode, 0b11, asm, (outs),10977 (ins !cast<RegisterOperand>(veclist # "1d"):$Vt,10978 GPR64sp:$Rn), []>;10979 10980 def v1d_POST : BaseSIMDLdStPost<0, 0, opcode, 0b11, asm,10981 (outs GPR64sp:$wback),10982 (ins !cast<RegisterOperand>(veclist # "1d"):$Vt,10983 GPR64sp:$Rn,10984 !cast<RegisterOperand>("GPR64pi" # Offset64):$Xm)>;10985 }10986 10987 defm : SIMDLdStAliases<BaseName, asm, "1d", Count, Offset64, 64>;10988}10989 10990multiclass SIMDLd1Multiple<string asm> {10991 defm One : BaseSIMDLd1<NAME, "One", asm, "VecListOne", 16, 8, 0b0111>;10992 defm Two : BaseSIMDLd1<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1010>;10993 defm Three : BaseSIMDLd1<NAME, "Three", asm, "VecListThree", 48, 24, 0b0110>;10994 defm Four : BaseSIMDLd1<NAME, "Four", asm, "VecListFour", 64, 32, 0b0010>;10995}10996 10997multiclass SIMDSt1Multiple<string asm> {10998 defm One : BaseSIMDSt1<NAME, "One", asm, "VecListOne", 16, 8, 0b0111>;10999 defm Two : BaseSIMDSt1<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1010>;11000 defm Three : BaseSIMDSt1<NAME, "Three", asm, "VecListThree", 48, 24, 0b0110>;11001 defm Four : BaseSIMDSt1<NAME, "Four", asm, "VecListFour", 64, 32, 0b0010>;11002}11003 11004multiclass SIMDLd2Multiple<string asm> {11005 defm Two : BaseSIMDLdN<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1000>;11006}11007 11008multiclass SIMDSt2Multiple<string asm> {11009 defm Two : BaseSIMDStN<NAME, "Two", asm, "VecListTwo", 32, 16, 0b1000>;11010}11011 11012multiclass SIMDLd3Multiple<string asm> {11013 defm Three : BaseSIMDLdN<NAME, "Three", asm, "VecListThree", 48, 24, 0b0100>;11014}11015 11016multiclass SIMDSt3Multiple<string asm> {11017 defm Three : BaseSIMDStN<NAME, "Three", asm, "VecListThree", 48, 24, 0b0100>;11018}11019 11020multiclass SIMDLd4Multiple<string asm> {11021 defm Four : BaseSIMDLdN<NAME, "Four", asm, "VecListFour", 64, 32, 0b0000>;11022}11023 11024multiclass SIMDSt4Multiple<string asm> {11025 defm Four : BaseSIMDStN<NAME, "Four", asm, "VecListFour", 64, 32, 0b0000>;11026}11027 11028//---11029// AdvSIMD Load/store single-element11030//---11031 11032class BaseSIMDLdStSingle<bit L, bit R, bits<3> opcode,11033 string asm, string operands, string cst,11034 dag oops, dag iops, list<dag> pattern>11035 : I<oops, iops, asm, operands, cst, pattern> {11036 bits<5> Vt;11037 bits<5> Rn;11038 let Inst{31} = 0;11039 let Inst{29-24} = 0b001101;11040 let Inst{22} = L;11041 let Inst{21} = R;11042 let Inst{15-13} = opcode;11043 let Inst{9-5} = Rn;11044 let Inst{4-0} = Vt;11045}11046 11047class BaseSIMDLdStSingleTied<bit L, bit R, bits<3> opcode,11048 string asm, string operands, string cst,11049 dag oops, dag iops, list<dag> pattern>11050 : I<oops, iops, asm, operands, "$Vt = $dst," # cst, pattern> {11051 bits<5> Vt;11052 bits<5> Rn;11053 let Inst{31} = 0;11054 let Inst{29-24} = 0b001101;11055 let Inst{22} = L;11056 let Inst{21} = R;11057 let Inst{15-13} = opcode;11058 let Inst{9-5} = Rn;11059 let Inst{4-0} = Vt;11060}11061 11062 11063let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in11064class BaseSIMDLdR<bit Q, bit R, bits<3> opcode, bit S, bits<2> size, string asm,11065 DAGOperand listtype>11066 : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn]", "",11067 (outs listtype:$Vt), (ins GPR64sp:$Rn),11068 []> {11069 let Inst{30} = Q;11070 let Inst{23} = 0;11071 let Inst{20-16} = 0b00000;11072 let Inst{12} = S;11073 let Inst{11-10} = size;11074}11075let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in11076class BaseSIMDLdRPost<bit Q, bit R, bits<3> opcode, bit S, bits<2> size,11077 string asm, DAGOperand listtype, DAGOperand GPR64pi>11078 : BaseSIMDLdStSingle<1, R, opcode, asm, "\t$Vt, [$Rn], $Xm",11079 "$Rn = $wback",11080 (outs GPR64sp:$wback, listtype:$Vt),11081 (ins GPR64sp:$Rn, GPR64pi:$Xm), []> {11082 bits<5> Xm;11083 let Inst{30} = Q;11084 let Inst{23} = 1;11085 let Inst{20-16} = Xm;11086 let Inst{12} = S;11087 let Inst{11-10} = size;11088}11089 11090multiclass SIMDLdrAliases<string BaseName, string asm, string layout, string Count,11091 int Offset, int Size> {11092 // E.g. "ld1r { v0.8b }, [x1], #1"11093 // "ld1r.8b\t$Vt, [$Rn], #1"11094 // may get mapped to11095 // (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR)11096 def : InstAlias<asm # "\t$Vt, [$Rn], #" # Offset,11097 (!cast<Instruction>(BaseName # "v" # layout # "_POST")11098 GPR64sp:$Rn,11099 !cast<RegisterOperand>("VecList" # Count # layout):$Vt,11100 XZR), 1>;11101 11102 // E.g. "ld1r.8b { v0 }, [x1], #1"11103 // "ld1r.8b\t$Vt, [$Rn], #1"11104 // may get mapped to11105 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR)11106 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], #" # Offset,11107 (!cast<Instruction>(BaseName # "v" # layout # "_POST")11108 GPR64sp:$Rn,11109 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,11110 XZR), 0>;11111 11112 // E.g. "ld1r.8b { v0 }, [x1]"11113 // "ld1r.8b\t$Vt, [$Rn]"11114 // may get mapped to11115 // (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn)11116 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn]",11117 (!cast<Instruction>(BaseName # "v" # layout)11118 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,11119 GPR64sp:$Rn), 0>;11120 11121 // E.g. "ld1r.8b { v0 }, [x1], x2"11122 // "ld1r.8b\t$Vt, [$Rn], $Xm"11123 // may get mapped to11124 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm)11125 def : InstAlias<asm # "." # layout # "\t$Vt, [$Rn], $Xm",11126 (!cast<Instruction>(BaseName # "v" # layout # "_POST")11127 GPR64sp:$Rn,11128 !cast<RegisterOperand>("VecList" # Count # Size):$Vt,11129 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>;11130}11131 11132multiclass SIMDLdR<bit R, bits<3> opcode, bit S, string asm, string Count,11133 int Offset1, int Offset2, int Offset4, int Offset8> {11134 def v8b : BaseSIMDLdR<0, R, opcode, S, 0b00, asm,11135 !cast<DAGOperand>("VecList" # Count # "8b")>;11136 def v16b: BaseSIMDLdR<1, R, opcode, S, 0b00, asm,11137 !cast<DAGOperand>("VecList" # Count #"16b")>;11138 def v4h : BaseSIMDLdR<0, R, opcode, S, 0b01, asm,11139 !cast<DAGOperand>("VecList" # Count #"4h")>;11140 def v8h : BaseSIMDLdR<1, R, opcode, S, 0b01, asm,11141 !cast<DAGOperand>("VecList" # Count #"8h")>;11142 def v2s : BaseSIMDLdR<0, R, opcode, S, 0b10, asm,11143 !cast<DAGOperand>("VecList" # Count #"2s")>;11144 def v4s : BaseSIMDLdR<1, R, opcode, S, 0b10, asm,11145 !cast<DAGOperand>("VecList" # Count #"4s")>;11146 def v1d : BaseSIMDLdR<0, R, opcode, S, 0b11, asm,11147 !cast<DAGOperand>("VecList" # Count #"1d")>;11148 def v2d : BaseSIMDLdR<1, R, opcode, S, 0b11, asm,11149 !cast<DAGOperand>("VecList" # Count #"2d")>;11150 11151 def v8b_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b00, asm,11152 !cast<DAGOperand>("VecList" # Count # "8b"),11153 !cast<DAGOperand>("GPR64pi" # Offset1)>;11154 def v16b_POST: BaseSIMDLdRPost<1, R, opcode, S, 0b00, asm,11155 !cast<DAGOperand>("VecList" # Count # "16b"),11156 !cast<DAGOperand>("GPR64pi" # Offset1)>;11157 def v4h_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b01, asm,11158 !cast<DAGOperand>("VecList" # Count # "4h"),11159 !cast<DAGOperand>("GPR64pi" # Offset2)>;11160 def v8h_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b01, asm,11161 !cast<DAGOperand>("VecList" # Count # "8h"),11162 !cast<DAGOperand>("GPR64pi" # Offset2)>;11163 def v2s_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b10, asm,11164 !cast<DAGOperand>("VecList" # Count # "2s"),11165 !cast<DAGOperand>("GPR64pi" # Offset4)>;11166 def v4s_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b10, asm,11167 !cast<DAGOperand>("VecList" # Count # "4s"),11168 !cast<DAGOperand>("GPR64pi" # Offset4)>;11169 def v1d_POST : BaseSIMDLdRPost<0, R, opcode, S, 0b11, asm,11170 !cast<DAGOperand>("VecList" # Count # "1d"),11171 !cast<DAGOperand>("GPR64pi" # Offset8)>;11172 def v2d_POST : BaseSIMDLdRPost<1, R, opcode, S, 0b11, asm,11173 !cast<DAGOperand>("VecList" # Count # "2d"),11174 !cast<DAGOperand>("GPR64pi" # Offset8)>;11175 11176 defm : SIMDLdrAliases<NAME, asm, "8b", Count, Offset1, 64>;11177 defm : SIMDLdrAliases<NAME, asm, "16b", Count, Offset1, 128>;11178 defm : SIMDLdrAliases<NAME, asm, "4h", Count, Offset2, 64>;11179 defm : SIMDLdrAliases<NAME, asm, "8h", Count, Offset2, 128>;11180 defm : SIMDLdrAliases<NAME, asm, "2s", Count, Offset4, 64>;11181 defm : SIMDLdrAliases<NAME, asm, "4s", Count, Offset4, 128>;11182 defm : SIMDLdrAliases<NAME, asm, "1d", Count, Offset8, 64>;11183 defm : SIMDLdrAliases<NAME, asm, "2d", Count, Offset8, 128>;11184}11185 11186class SIMDLdStSingleB<bit L, bit R, bits<3> opcode, string asm,11187 dag oops, dag iops, list<dag> pattern>11188 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,11189 pattern> {11190 // idx encoded in Q:S:size fields.11191 bits<4> idx;11192 let Inst{30} = idx{3};11193 let Inst{23} = 0;11194 let Inst{20-16} = 0b00000;11195 let Inst{12} = idx{2};11196 let Inst{11-10} = idx{1-0};11197}11198class SIMDLdStSingleBTied<bit L, bit R, bits<3> opcode, string asm,11199 dag oops, dag iops, list<dag> pattern>11200 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",11201 oops, iops, pattern> {11202 // idx encoded in Q:S:size fields.11203 bits<4> idx;11204 let Inst{30} = idx{3};11205 let Inst{23} = 0;11206 let Inst{20-16} = 0b00000;11207 let Inst{12} = idx{2};11208 let Inst{11-10} = idx{1-0};11209}11210class SIMDLdStSingleBPost<bit L, bit R, bits<3> opcode, string asm,11211 dag oops, dag iops>11212 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",11213 "$Rn = $wback", oops, iops, []> {11214 // idx encoded in Q:S:size fields.11215 bits<4> idx;11216 bits<5> Xm;11217 let Inst{30} = idx{3};11218 let Inst{23} = 1;11219 let Inst{20-16} = Xm;11220 let Inst{12} = idx{2};11221 let Inst{11-10} = idx{1-0};11222}11223class SIMDLdStSingleBTiedPost<bit L, bit R, bits<3> opcode, string asm,11224 dag oops, dag iops>11225 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",11226 "$Rn = $wback", oops, iops, []> {11227 // idx encoded in Q:S:size fields.11228 bits<4> idx;11229 bits<5> Xm;11230 let Inst{30} = idx{3};11231 let Inst{23} = 1;11232 let Inst{20-16} = Xm;11233 let Inst{12} = idx{2};11234 let Inst{11-10} = idx{1-0};11235}11236 11237class SIMDLdStSingleH<bit L, bit R, bits<3> opcode, bit size, string asm,11238 dag oops, dag iops, list<dag> pattern>11239 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,11240 pattern> {11241 // idx encoded in Q:S:size<1> fields.11242 bits<3> idx;11243 let Inst{30} = idx{2};11244 let Inst{23} = 0;11245 let Inst{20-16} = 0b00000;11246 let Inst{12} = idx{1};11247 let Inst{11} = idx{0};11248 let Inst{10} = size;11249}11250class SIMDLdStSingleHTied<bit L, bit R, bits<3> opcode, bit size, string asm,11251 dag oops, dag iops, list<dag> pattern>11252 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",11253 oops, iops, pattern> {11254 // idx encoded in Q:S:size<1> fields.11255 bits<3> idx;11256 let Inst{30} = idx{2};11257 let Inst{23} = 0;11258 let Inst{20-16} = 0b00000;11259 let Inst{12} = idx{1};11260 let Inst{11} = idx{0};11261 let Inst{10} = size;11262}11263 11264class SIMDLdStSingleHPost<bit L, bit R, bits<3> opcode, bit size, string asm,11265 dag oops, dag iops>11266 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",11267 "$Rn = $wback", oops, iops, []> {11268 // idx encoded in Q:S:size<1> fields.11269 bits<3> idx;11270 bits<5> Xm;11271 let Inst{30} = idx{2};11272 let Inst{23} = 1;11273 let Inst{20-16} = Xm;11274 let Inst{12} = idx{1};11275 let Inst{11} = idx{0};11276 let Inst{10} = size;11277}11278class SIMDLdStSingleHTiedPost<bit L, bit R, bits<3> opcode, bit size, string asm,11279 dag oops, dag iops>11280 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",11281 "$Rn = $wback", oops, iops, []> {11282 // idx encoded in Q:S:size<1> fields.11283 bits<3> idx;11284 bits<5> Xm;11285 let Inst{30} = idx{2};11286 let Inst{23} = 1;11287 let Inst{20-16} = Xm;11288 let Inst{12} = idx{1};11289 let Inst{11} = idx{0};11290 let Inst{10} = size;11291}11292class SIMDLdStSingleS<bit L, bit R, bits<3> opcode, bits<2> size, string asm,11293 dag oops, dag iops, list<dag> pattern>11294 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,11295 pattern> {11296 // idx encoded in Q:S fields.11297 bits<2> idx;11298 let Inst{30} = idx{1};11299 let Inst{23} = 0;11300 let Inst{20-16} = 0b00000;11301 let Inst{12} = idx{0};11302 let Inst{11-10} = size;11303}11304class SIMDLdStSingleSTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm,11305 dag oops, dag iops, list<dag> pattern>11306 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",11307 oops, iops, pattern> {11308 // idx encoded in Q:S fields.11309 bits<2> idx;11310 let Inst{30} = idx{1};11311 let Inst{23} = 0;11312 let Inst{20-16} = 0b00000;11313 let Inst{12} = idx{0};11314 let Inst{11-10} = size;11315}11316class SIMDLdStSingleSPost<bit L, bit R, bits<3> opcode, bits<2> size,11317 string asm, dag oops, dag iops>11318 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",11319 "$Rn = $wback", oops, iops, []> {11320 // idx encoded in Q:S fields.11321 bits<2> idx;11322 bits<5> Xm;11323 let Inst{30} = idx{1};11324 let Inst{23} = 1;11325 let Inst{20-16} = Xm;11326 let Inst{12} = idx{0};11327 let Inst{11-10} = size;11328}11329class SIMDLdStSingleSTiedPost<bit L, bit R, bits<3> opcode, bits<2> size,11330 string asm, dag oops, dag iops>11331 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",11332 "$Rn = $wback", oops, iops, []> {11333 // idx encoded in Q:S fields.11334 bits<2> idx;11335 bits<5> Xm;11336 let Inst{30} = idx{1};11337 let Inst{23} = 1;11338 let Inst{20-16} = Xm;11339 let Inst{12} = idx{0};11340 let Inst{11-10} = size;11341}11342class SIMDLdStSingleD<bit L, bit R, bits<3> opcode, bits<2> size, string asm,11343 dag oops, dag iops, list<dag> pattern>11344 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "", oops, iops,11345 pattern> {11346 // idx encoded in Q field.11347 bits<1> idx;11348 let Inst{30} = idx;11349 let Inst{23} = 0;11350 let Inst{20-16} = 0b00000;11351 let Inst{12} = 0;11352 let Inst{11-10} = size;11353}11354class SIMDLdStSingleDTied<bit L, bit R, bits<3> opcode, bits<2> size, string asm,11355 dag oops, dag iops, list<dag> pattern>11356 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn]", "",11357 oops, iops, pattern> {11358 // idx encoded in Q field.11359 bits<1> idx;11360 let Inst{30} = idx;11361 let Inst{23} = 0;11362 let Inst{20-16} = 0b00000;11363 let Inst{12} = 0;11364 let Inst{11-10} = size;11365}11366class SIMDLdStSingleDPost<bit L, bit R, bits<3> opcode, bits<2> size,11367 string asm, dag oops, dag iops>11368 : BaseSIMDLdStSingle<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",11369 "$Rn = $wback", oops, iops, []> {11370 // idx encoded in Q field.11371 bits<1> idx;11372 bits<5> Xm;11373 let Inst{30} = idx;11374 let Inst{23} = 1;11375 let Inst{20-16} = Xm;11376 let Inst{12} = 0;11377 let Inst{11-10} = size;11378}11379class SIMDLdStSingleDTiedPost<bit L, bit R, bits<3> opcode, bits<2> size,11380 string asm, dag oops, dag iops>11381 : BaseSIMDLdStSingleTied<L, R, opcode, asm, "\t$Vt$idx, [$Rn], $Xm",11382 "$Rn = $wback", oops, iops, []> {11383 // idx encoded in Q field.11384 bits<1> idx;11385 bits<5> Xm;11386 let Inst{30} = idx;11387 let Inst{23} = 1;11388 let Inst{20-16} = Xm;11389 let Inst{12} = 0;11390 let Inst{11-10} = size;11391}11392 11393let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in11394multiclass SIMDLdSingleBTied<bit R, bits<3> opcode, string asm,11395 RegisterOperand listtype,11396 RegisterOperand GPR64pi> {11397 def i8 : SIMDLdStSingleBTied<1, R, opcode, asm,11398 (outs listtype:$dst),11399 (ins listtype:$Vt, VectorIndexB:$idx,11400 GPR64sp:$Rn), []>;11401 11402 def i8_POST : SIMDLdStSingleBTiedPost<1, R, opcode, asm,11403 (outs GPR64sp:$wback, listtype:$dst),11404 (ins listtype:$Vt, VectorIndexB:$idx,11405 GPR64sp:$Rn, GPR64pi:$Xm)>;11406}11407let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in11408multiclass SIMDLdSingleHTied<bit R, bits<3> opcode, bit size, string asm,11409 RegisterOperand listtype,11410 RegisterOperand GPR64pi> {11411 def i16 : SIMDLdStSingleHTied<1, R, opcode, size, asm,11412 (outs listtype:$dst),11413 (ins listtype:$Vt, VectorIndexH:$idx,11414 GPR64sp:$Rn), []>;11415 11416 def i16_POST : SIMDLdStSingleHTiedPost<1, R, opcode, size, asm,11417 (outs GPR64sp:$wback, listtype:$dst),11418 (ins listtype:$Vt, VectorIndexH:$idx,11419 GPR64sp:$Rn, GPR64pi:$Xm)>;11420}11421let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in11422multiclass SIMDLdSingleSTied<bit R, bits<3> opcode, bits<2> size,string asm,11423 RegisterOperand listtype,11424 RegisterOperand GPR64pi> {11425 def i32 : SIMDLdStSingleSTied<1, R, opcode, size, asm,11426 (outs listtype:$dst),11427 (ins listtype:$Vt, VectorIndexS:$idx,11428 GPR64sp:$Rn), []>;11429 11430 def i32_POST : SIMDLdStSingleSTiedPost<1, R, opcode, size, asm,11431 (outs GPR64sp:$wback, listtype:$dst),11432 (ins listtype:$Vt, VectorIndexS:$idx,11433 GPR64sp:$Rn, GPR64pi:$Xm)>;11434}11435let mayLoad = 1, mayStore = 0, hasSideEffects = 0 in11436multiclass SIMDLdSingleDTied<bit R, bits<3> opcode, bits<2> size, string asm,11437 RegisterOperand listtype, RegisterOperand GPR64pi> {11438 def i64 : SIMDLdStSingleDTied<1, R, opcode, size, asm,11439 (outs listtype:$dst),11440 (ins listtype:$Vt, VectorIndexD:$idx,11441 GPR64sp:$Rn), []>;11442 11443 def i64_POST : SIMDLdStSingleDTiedPost<1, R, opcode, size, asm,11444 (outs GPR64sp:$wback, listtype:$dst),11445 (ins listtype:$Vt, VectorIndexD:$idx,11446 GPR64sp:$Rn, GPR64pi:$Xm)>;11447}11448let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in11449multiclass SIMDStSingleB<bit R, bits<3> opcode, string asm,11450 RegisterOperand listtype, RegisterOperand GPR64pi> {11451 def i8 : SIMDLdStSingleB<0, R, opcode, asm,11452 (outs), (ins listtype:$Vt, VectorIndexB:$idx,11453 GPR64sp:$Rn), []>;11454 11455 def i8_POST : SIMDLdStSingleBPost<0, R, opcode, asm,11456 (outs GPR64sp:$wback),11457 (ins listtype:$Vt, VectorIndexB:$idx,11458 GPR64sp:$Rn, GPR64pi:$Xm)>;11459}11460let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in11461multiclass SIMDStSingleH<bit R, bits<3> opcode, bit size, string asm,11462 RegisterOperand listtype, RegisterOperand GPR64pi> {11463 def i16 : SIMDLdStSingleH<0, R, opcode, size, asm,11464 (outs), (ins listtype:$Vt, VectorIndexH:$idx,11465 GPR64sp:$Rn), []>;11466 11467 def i16_POST : SIMDLdStSingleHPost<0, R, opcode, size, asm,11468 (outs GPR64sp:$wback),11469 (ins listtype:$Vt, VectorIndexH:$idx,11470 GPR64sp:$Rn, GPR64pi:$Xm)>;11471}11472let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in11473multiclass SIMDStSingleS<bit R, bits<3> opcode, bits<2> size,string asm,11474 RegisterOperand listtype, RegisterOperand GPR64pi> {11475 def i32 : SIMDLdStSingleS<0, R, opcode, size, asm,11476 (outs), (ins listtype:$Vt, VectorIndexS:$idx,11477 GPR64sp:$Rn), []>;11478 11479 def i32_POST : SIMDLdStSingleSPost<0, R, opcode, size, asm,11480 (outs GPR64sp:$wback),11481 (ins listtype:$Vt, VectorIndexS:$idx,11482 GPR64sp:$Rn, GPR64pi:$Xm)>;11483}11484let mayLoad = 0, mayStore = 1, hasSideEffects = 0 in11485multiclass SIMDStSingleD<bit R, bits<3> opcode, bits<2> size, string asm,11486 RegisterOperand listtype, RegisterOperand GPR64pi> {11487 def i64 : SIMDLdStSingleD<0, R, opcode, size, asm,11488 (outs), (ins listtype:$Vt, VectorIndexD:$idx,11489 GPR64sp:$Rn), []>;11490 11491 def i64_POST : SIMDLdStSingleDPost<0, R, opcode, size, asm,11492 (outs GPR64sp:$wback),11493 (ins listtype:$Vt, VectorIndexD:$idx,11494 GPR64sp:$Rn, GPR64pi:$Xm)>;11495}11496 11497multiclass SIMDLdStSingleAliases<string asm, string layout, string Type,11498 string Count, int Offset, Operand idxtype> {11499 // E.g. "ld1 { v0.8b }[0], [x1], #1"11500 // "ld1\t$Vt, [$Rn], #1"11501 // may get mapped to11502 // (LD1Rv8b_POST VecListOne8b:$Vt, GPR64sp:$Rn, XZR)11503 def : InstAlias<asm # "\t$Vt$idx, [$Rn], #" # Offset,11504 (!cast<Instruction>(NAME # Type # "_POST")11505 GPR64sp:$Rn,11506 !cast<RegisterOperand>("VecList" # Count # layout):$Vt,11507 idxtype:$idx, XZR), 1>;11508 11509 // E.g. "ld1.8b { v0 }[0], [x1], #1"11510 // "ld1.8b\t$Vt, [$Rn], #1"11511 // may get mapped to11512 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, XZR)11513 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], #" # Offset,11514 (!cast<Instruction>(NAME # Type # "_POST")11515 GPR64sp:$Rn,11516 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt,11517 idxtype:$idx, XZR), 0>;11518 11519 // E.g. "ld1.8b { v0 }[0], [x1]"11520 // "ld1.8b\t$Vt, [$Rn]"11521 // may get mapped to11522 // (LD1Rv8b VecListOne64:$Vt, GPR64sp:$Rn)11523 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn]",11524 (!cast<Instruction>(NAME # Type)11525 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt,11526 idxtype:$idx, GPR64sp:$Rn), 0>;11527 11528 // E.g. "ld1.8b { v0 }[0], [x1], x2"11529 // "ld1.8b\t$Vt, [$Rn], $Xm"11530 // may get mapped to11531 // (LD1Rv8b_POST VecListOne64:$Vt, GPR64sp:$Rn, GPR64pi1:$Xm)11532 def : InstAlias<asm # "." # layout # "\t$Vt$idx, [$Rn], $Xm",11533 (!cast<Instruction>(NAME # Type # "_POST")11534 GPR64sp:$Rn,11535 !cast<RegisterOperand>("VecList" # Count # "128"):$Vt,11536 idxtype:$idx,11537 !cast<RegisterOperand>("GPR64pi" # Offset):$Xm), 0>;11538}11539 11540multiclass SIMDLdSt1SingleAliases<string asm> {11541 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "One", 1, VectorIndexB>;11542 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "One", 2, VectorIndexH>;11543 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "One", 4, VectorIndexS>;11544 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "One", 8, VectorIndexD>;11545}11546 11547multiclass SIMDLdSt2SingleAliases<string asm> {11548 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "Two", 2, VectorIndexB>;11549 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Two", 4, VectorIndexH>;11550 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Two", 8, VectorIndexS>;11551 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Two", 16, VectorIndexD>;11552}11553 11554multiclass SIMDLdSt3SingleAliases<string asm> {11555 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "Three", 3, VectorIndexB>;11556 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Three", 6, VectorIndexH>;11557 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Three", 12, VectorIndexS>;11558 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Three", 24, VectorIndexD>;11559}11560 11561multiclass SIMDLdSt4SingleAliases<string asm> {11562 defm "" : SIMDLdStSingleAliases<asm, "b", "i8", "Four", 4, VectorIndexB>;11563 defm "" : SIMDLdStSingleAliases<asm, "h", "i16", "Four", 8, VectorIndexH>;11564 defm "" : SIMDLdStSingleAliases<asm, "s", "i32", "Four", 16, VectorIndexS>;11565 defm "" : SIMDLdStSingleAliases<asm, "d", "i64", "Four", 32, VectorIndexD>;11566}11567} // end of 'let Predicates = [HasNEON]'11568 11569//----------------------------------------------------------------------------11570// AdvSIMD v8.1 Rounding Double Multiply Add/Subtract11571//----------------------------------------------------------------------------11572 11573let Predicates = [HasNEON, HasRDM] in {11574 11575class BaseSIMDThreeSameVectorTiedR0<bit Q, bit U, bits<2> size, bits<5> opcode,11576 RegisterOperand regtype, string asm,11577 string kind, list<dag> pattern>11578 : BaseSIMDThreeSameVectorTied<Q, U, {size,0}, opcode, regtype, asm, kind,11579 pattern> {11580}11581multiclass SIMDThreeSameVectorSQRDMLxHTiedHS<bit U, bits<5> opc, string asm,11582 SDPatternOperator op> {11583 def v4i16 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b01, opc, V64, asm, ".4h",11584 [(set (v4i16 V64:$dst),11585 (v4i16 (op (v4i16 V64:$Rd), (v4i16 V64:$Rn), (v4i16 V64:$Rm))))]>;11586 def v8i16 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b01, opc, V128, asm, ".8h",11587 [(set (v8i16 V128:$dst),11588 (v8i16 (op (v8i16 V128:$Rd), (v8i16 V128:$Rn), (v8i16 V128:$Rm))))]>;11589 def v2i32 : BaseSIMDThreeSameVectorTiedR0<0, U, 0b10, opc, V64, asm, ".2s",11590 [(set (v2i32 V64:$dst),11591 (v2i32 (op (v2i32 V64:$Rd), (v2i32 V64:$Rn), (v2i32 V64:$Rm))))]>;11592 def v4i32 : BaseSIMDThreeSameVectorTiedR0<1, U, 0b10, opc, V128, asm, ".4s",11593 [(set (v4i32 V128:$dst),11594 (v4i32 (op (v4i32 V128:$Rd), (v4i32 V128:$Rn), (v4i32 V128:$Rm))))]>;11595}11596 11597multiclass SIMDIndexedSQRDMLxHSDTied<bit U, bits<4> opc, string asm,11598 SDPatternOperator op> {11599 def v4i16_indexed : BaseSIMDIndexedTied<0, U, 0, 0b01, opc,11600 V64, V64, V128_lo, VectorIndexH,11601 asm, ".4h", ".4h", ".4h", ".h",11602 [(set (v4i16 V64:$dst),11603 (v4i16 (op (v4i16 V64:$Rd), (v4i16 V64:$Rn),11604 (dup_v8i16 (v8i16 V128_lo:$Rm),11605 VectorIndexH:$idx))))]> {11606 bits<3> idx;11607 let Inst{11} = idx{2};11608 let Inst{21} = idx{1};11609 let Inst{20} = idx{0};11610 }11611 11612 def v8i16_indexed : BaseSIMDIndexedTied<1, U, 0, 0b01, opc,11613 V128, V128, V128_lo, VectorIndexH,11614 asm, ".8h", ".8h", ".8h", ".h",11615 [(set (v8i16 V128:$dst),11616 (v8i16 (op (v8i16 V128:$Rd), (v8i16 V128:$Rn),11617 (v8i16 (AArch64duplane16 (v8i16 V128_lo:$Rm),11618 VectorIndexH:$idx)))))]> {11619 bits<3> idx;11620 let Inst{11} = idx{2};11621 let Inst{21} = idx{1};11622 let Inst{20} = idx{0};11623 }11624 11625 def v2i32_indexed : BaseSIMDIndexedTied<0, U, 0, 0b10, opc,11626 V64, V64, V128, VectorIndexS,11627 asm, ".2s", ".2s", ".2s", ".s",11628 [(set (v2i32 V64:$dst),11629 (v2i32 (op (v2i32 V64:$Rd), (v2i32 V64:$Rn),11630 (dup_v4i32 (v4i32 V128:$Rm), VectorIndexS:$idx))))]> {11631 bits<2> idx;11632 let Inst{11} = idx{1};11633 let Inst{21} = idx{0};11634 }11635 11636 def v4i32_indexed : BaseSIMDIndexedTied<1, U, 0, 0b10, opc,11637 V128, V128, V128, VectorIndexS,11638 asm, ".4s", ".4s", ".4s", ".s",11639 [(set (v4i32 V128:$dst),11640 (v4i32 (op (v4i32 V128:$Rd), (v4i32 V128:$Rn),11641 (v4i32 (AArch64duplane32 (v4i32 V128:$Rm),11642 VectorIndexS:$idx)))))]> {11643 bits<2> idx;11644 let Inst{11} = idx{1};11645 let Inst{21} = idx{0};11646 }11647 11648 def v1i16_indexed : BaseSIMDIndexedTied<1, U, 1, 0b01, opc,11649 FPR16Op, FPR16Op, V128_lo,11650 VectorIndexH, asm, ".h", "", "", ".h",11651 []> {11652 bits<3> idx;11653 let Inst{11} = idx{2};11654 let Inst{21} = idx{1};11655 let Inst{20} = idx{0};11656 }11657 11658 def v1i32_indexed : BaseSIMDIndexedTied<1, U, 1, 0b10, opc,11659 FPR32Op, FPR32Op, V128, VectorIndexS,11660 asm, ".s", "", "", ".s",11661 [(set (i32 FPR32Op:$dst),11662 (i32 (op (i32 FPR32Op:$Rd), (i32 FPR32Op:$Rn),11663 (i32 (vector_extract (v4i32 V128:$Rm),11664 VectorIndexS:$idx)))))]> {11665 bits<2> idx;11666 let Inst{11} = idx{1};11667 let Inst{21} = idx{0};11668 }11669}11670} // let Predicates = [HasNeon, HasRDM]11671 11672//----------------------------------------------------------------------------11673// ARMv8.3 Complex ADD/MLA instructions11674//----------------------------------------------------------------------------11675 11676class ComplexRotationOperand<int Angle, int Remainder, string Type>11677 : AsmOperandClass {11678 let PredicateMethod = "isComplexRotation<" # Angle # ", " # Remainder # ">";11679 let DiagnosticType = "InvalidComplexRotation" # Type;11680 let Name = "ComplexRotation" # Type;11681}11682def complexrotateop : Operand<i32>, TImmLeaf<i32, [{ return Imm >= 0 && Imm <= 270; }],11683 SDNodeXForm<imm, [{11684 return CurDAG->getTargetConstant((N->getSExtValue() / 90), SDLoc(N), MVT::i32);11685}]>> {11686 let ParserMatchClass = ComplexRotationOperand<90, 0, "Even">;11687 let PrintMethod = "printComplexRotationOp<90, 0>";11688}11689def complexrotateopodd : Operand<i32>, TImmLeaf<i32, [{ return Imm >= 0 && Imm <= 270; }],11690 SDNodeXForm<imm, [{11691 return CurDAG->getTargetConstant(((N->getSExtValue() - 90) / 180), SDLoc(N), MVT::i32);11692}]>> {11693 let ParserMatchClass = ComplexRotationOperand<180, 90, "Odd">;11694 let PrintMethod = "printComplexRotationOp<180, 90>";11695}11696let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in11697class BaseSIMDThreeSameVectorComplex<bit Q, bit U, bits<2> size, bits<3> opcode,11698 RegisterOperand regtype, Operand rottype,11699 string asm, string kind, list<dag> pattern>11700 : I<(outs regtype:$Rd), (ins regtype:$Rn, regtype:$Rm, rottype:$rot), asm,11701 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $rot"11702 "|" # kind # "\t$Rd, $Rn, $Rm, $rot}", "", pattern>,11703 Sched<[!if(Q, WriteVq, WriteVd)]> {11704 bits<5> Rd;11705 bits<5> Rn;11706 bits<5> Rm;11707 bits<1> rot;11708 let Inst{31} = 0;11709 let Inst{30} = Q;11710 let Inst{29} = U;11711 let Inst{28-24} = 0b01110;11712 let Inst{23-22} = size;11713 let Inst{21} = 0;11714 let Inst{20-16} = Rm;11715 let Inst{15-13} = opcode;11716 // Non-tied version (FCADD) only has one rotation bit11717 let Inst{12} = rot;11718 let Inst{11} = 0;11719 let Inst{10} = 1;11720 let Inst{9-5} = Rn;11721 let Inst{4-0} = Rd;11722}11723 11724//8.3 CompNum - Floating-point complex number support11725multiclass SIMDThreeSameVectorComplexHSD<bit U, bits<3> opcode, Operand rottype,11726 string asm, SDPatternOperator OpNode>{11727 let Predicates = [HasComplxNum, HasNEON, HasFullFP16] in {11728 def v4f16 : BaseSIMDThreeSameVectorComplex<0, U, 0b01, opcode, V64, rottype,11729 asm, ".4h",11730 [(set (v4f16 V64:$dst), (OpNode (v4f16 V64:$Rd),11731 (v4f16 V64:$Rn),11732 (v4f16 V64:$Rm),11733 (i32 rottype:$rot)))]>;11734 11735 def v8f16 : BaseSIMDThreeSameVectorComplex<1, U, 0b01, opcode, V128, rottype,11736 asm, ".8h",11737 [(set (v8f16 V128:$dst), (OpNode (v8f16 V128:$Rd),11738 (v8f16 V128:$Rn),11739 (v8f16 V128:$Rm),11740 (i32 rottype:$rot)))]>;11741 }11742 11743 let Predicates = [HasComplxNum, HasNEON] in {11744 def v2f32 : BaseSIMDThreeSameVectorComplex<0, U, 0b10, opcode, V64, rottype,11745 asm, ".2s",11746 [(set (v2f32 V64:$dst), (OpNode (v2f32 V64:$Rd),11747 (v2f32 V64:$Rn),11748 (v2f32 V64:$Rm),11749 (i32 rottype:$rot)))]>;11750 11751 def v4f32 : BaseSIMDThreeSameVectorComplex<1, U, 0b10, opcode, V128, rottype,11752 asm, ".4s",11753 [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd),11754 (v4f32 V128:$Rn),11755 (v4f32 V128:$Rm),11756 (i32 rottype:$rot)))]>;11757 11758 def v2f64 : BaseSIMDThreeSameVectorComplex<1, U, 0b11, opcode, V128, rottype,11759 asm, ".2d",11760 [(set (v2f64 V128:$dst), (OpNode (v2f64 V128:$Rd),11761 (v2f64 V128:$Rn),11762 (v2f64 V128:$Rm),11763 (i32 rottype:$rot)))]>;11764 }11765}11766 11767let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in11768class BaseSIMDThreeSameVectorTiedComplex<bit Q, bit U, bits<2> size,11769 bits<3> opcode,11770 RegisterOperand regtype,11771 Operand rottype, string asm,11772 string kind, list<dag> pattern>11773 : I<(outs regtype:$dst),11774 (ins regtype:$Rd, regtype:$Rn, regtype:$Rm, rottype:$rot), asm,11775 "{\t$Rd" # kind # ", $Rn" # kind # ", $Rm" # kind # ", $rot"11776 "|" # kind # "\t$Rd, $Rn, $Rm, $rot}", "$Rd = $dst", pattern>,11777 Sched<[!if(Q, WriteVq, WriteVd)]> {11778 bits<5> Rd;11779 bits<5> Rn;11780 bits<5> Rm;11781 bits<2> rot;11782 let Inst{31} = 0;11783 let Inst{30} = Q;11784 let Inst{29} = U;11785 let Inst{28-24} = 0b01110;11786 let Inst{23-22} = size;11787 let Inst{21} = 0;11788 let Inst{20-16} = Rm;11789 let Inst{15-13} = opcode;11790 let Inst{12-11} = rot;11791 let Inst{10} = 1;11792 let Inst{9-5} = Rn;11793 let Inst{4-0} = Rd;11794}11795 11796multiclass SIMDThreeSameVectorTiedComplexHSD<bit U, bits<3> opcode,11797 Operand rottype, string asm,11798 SDPatternOperator OpNode> {11799 let Predicates = [HasComplxNum, HasNEON, HasFullFP16] in {11800 def v4f16 : BaseSIMDThreeSameVectorTiedComplex<0, U, 0b01, opcode, V64,11801 rottype, asm, ".4h",11802 [(set (v4f16 V64:$dst), (OpNode (v4f16 V64:$Rd),11803 (v4f16 V64:$Rn),11804 (v4f16 V64:$Rm),11805 (i32 rottype:$rot)))]>;11806 11807 def v8f16 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b01, opcode, V128,11808 rottype, asm, ".8h",11809 [(set (v8f16 V128:$dst), (OpNode (v8f16 V128:$Rd),11810 (v8f16 V128:$Rn),11811 (v8f16 V128:$Rm),11812 (i32 rottype:$rot)))]>;11813 }11814 11815 let Predicates = [HasComplxNum, HasNEON] in {11816 def v2f32 : BaseSIMDThreeSameVectorTiedComplex<0, U, 0b10, opcode, V64,11817 rottype, asm, ".2s",11818 [(set (v2f32 V64:$dst), (OpNode (v2f32 V64:$Rd),11819 (v2f32 V64:$Rn),11820 (v2f32 V64:$Rm),11821 (i32 rottype:$rot)))]>;11822 11823 def v4f32 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b10, opcode, V128,11824 rottype, asm, ".4s",11825 [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd),11826 (v4f32 V128:$Rn),11827 (v4f32 V128:$Rm),11828 (i32 rottype:$rot)))]>;11829 11830 def v2f64 : BaseSIMDThreeSameVectorTiedComplex<1, U, 0b11, opcode, V128,11831 rottype, asm, ".2d",11832 [(set (v2f64 V128:$dst), (OpNode (v2f64 V128:$Rd),11833 (v2f64 V128:$Rn),11834 (v2f64 V128:$Rm),11835 (i32 rottype:$rot)))]>;11836 }11837}11838 11839let mayLoad = 0, mayStore = 0, hasSideEffects = 0, mayRaiseFPException = 1, Uses = [FPCR] in11840class BaseSIMDIndexedTiedComplex<bit Q, bit U, bit Scalar, bits<2> size,11841 bit opc1, bit opc2, RegisterOperand dst_reg,11842 RegisterOperand lhs_reg,11843 RegisterOperand rhs_reg, Operand vec_idx,11844 Operand rottype, string asm, string apple_kind,11845 string dst_kind, string lhs_kind,11846 string rhs_kind, list<dag> pattern>11847 : I<(outs dst_reg:$dst),11848 (ins dst_reg:$Rd, lhs_reg:$Rn, rhs_reg:$Rm, vec_idx:$idx, rottype:$rot),11849 asm,11850 "{\t$Rd" # dst_kind # ", $Rn" # lhs_kind # ", $Rm" # rhs_kind #11851 "$idx, $rot" # "|" # apple_kind #11852 "\t$Rd, $Rn, $Rm$idx, $rot}", "$Rd = $dst", pattern>,11853 Sched<[!if(Q, WriteVq, WriteVd)]> {11854 bits<5> Rd;11855 bits<5> Rn;11856 bits<5> Rm;11857 bits<2> rot;11858 11859 let Inst{31} = 0;11860 let Inst{30} = Q;11861 let Inst{29} = U;11862 let Inst{28} = Scalar;11863 let Inst{27-24} = 0b1111;11864 let Inst{23-22} = size;11865 // Bit 21 must be set by the derived class.11866 let Inst{20-16} = Rm;11867 let Inst{15} = opc1;11868 let Inst{14-13} = rot;11869 let Inst{12} = opc2;11870 // Bit 11 must be set by the derived class.11871 let Inst{10} = 0;11872 let Inst{9-5} = Rn;11873 let Inst{4-0} = Rd;11874}11875 11876// The complex instructions index by pairs of elements, so the VectorIndexes11877// don't match the lane types, and the index bits are different to the other11878// classes.11879multiclass SIMDIndexedTiedComplexHSD<bit opc1, bit opc2, Operand rottype,11880 string asm> {11881 let Predicates = [HasComplxNum, HasNEON, HasFullFP16] in {11882 def v4f16_indexed : BaseSIMDIndexedTiedComplex<0, 1, 0, 0b01, opc1, opc2, V64,11883 V64, V128, VectorIndexD, rottype, asm, ".4h", ".4h",11884 ".4h", ".h", []> {11885 bits<1> idx;11886 let Inst{11} = 0;11887 let Inst{21} = idx{0};11888 }11889 11890 def v8f16_indexed : BaseSIMDIndexedTiedComplex<1, 1, 0, 0b01, opc1, opc2,11891 V128, V128, V128, VectorIndexS, rottype, asm, ".8h",11892 ".8h", ".8h", ".h", []> {11893 bits<2> idx;11894 let Inst{11} = idx{1};11895 let Inst{21} = idx{0};11896 }11897 } // Predicates = HasComplxNum, HasNEON, HasFullFP16]11898 11899 let Predicates = [HasComplxNum, HasNEON] in {11900 def v4f32_indexed : BaseSIMDIndexedTiedComplex<1, 1, 0, 0b10, opc1, opc2,11901 V128, V128, V128, VectorIndexD, rottype, asm, ".4s",11902 ".4s", ".4s", ".s", []> {11903 bits<1> idx;11904 let Inst{11} = idx{0};11905 let Inst{21} = 0;11906 }11907 } // Predicates = [HasComplxNum, HasNEON]11908}11909 11910//----------------------------------------------------------------------------11911// Crypto extensions11912//----------------------------------------------------------------------------11913 11914let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in11915class AESBase<bits<4> opc, string asm, dag outs, dag ins, string cstr,11916 list<dag> pat>11917 : I<outs, ins, asm, "{\t$Rd.16b, $Rn.16b|.16b\t$Rd, $Rn}", cstr, pat>,11918 Sched<[WriteVq]>{11919 bits<5> Rd;11920 bits<5> Rn;11921 let Inst{31-16} = 0b0100111000101000;11922 let Inst{15-12} = opc;11923 let Inst{11-10} = 0b10;11924 let Inst{9-5} = Rn;11925 let Inst{4-0} = Rd;11926}11927 11928class AESInst<bits<4> opc, string asm, Intrinsic OpNode>11929 : AESBase<opc, asm, (outs V128:$Rd), (ins V128:$Rn), "",11930 [(set (v16i8 V128:$Rd), (OpNode (v16i8 V128:$Rn)))]>;11931 11932class AESTiedInst<bits<4> opc, string asm, Intrinsic OpNode>11933 : AESBase<opc, asm, (outs V128:$dst), (ins V128:$Rd, V128:$Rn),11934 "$Rd = $dst",11935 [(set (v16i8 V128:$dst),11936 (OpNode (v16i8 V128:$Rd), (v16i8 V128:$Rn)))]>;11937 11938let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in11939class SHA3OpTiedInst<bits<3> opc, string asm, string dst_lhs_kind,11940 dag oops, dag iops, list<dag> pat>11941 : I<oops, iops, asm,11942 "{\t$Rd" # dst_lhs_kind # ", $Rn" # dst_lhs_kind # ", $Rm.4s" #11943 "|.4s\t$Rd, $Rn, $Rm}", "$Rd = $dst", pat>,11944 Sched<[WriteVq]>{11945 bits<5> Rd;11946 bits<5> Rn;11947 bits<5> Rm;11948 let Inst{31-21} = 0b01011110000;11949 let Inst{20-16} = Rm;11950 let Inst{15} = 0;11951 let Inst{14-12} = opc;11952 let Inst{11-10} = 0b00;11953 let Inst{9-5} = Rn;11954 let Inst{4-0} = Rd;11955}11956 11957class SHATiedInstQSV<bits<3> opc, string asm, Intrinsic OpNode>11958 : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst),11959 (ins FPR128:$Rd, FPR32:$Rn, V128:$Rm),11960 [(set (v4i32 FPR128:$dst),11961 (OpNode (v4i32 FPR128:$Rd), (i32 FPR32:$Rn),11962 (v4i32 V128:$Rm)))]>;11963 11964class SHATiedInstVVV<bits<3> opc, string asm, Intrinsic OpNode>11965 : SHA3OpTiedInst<opc, asm, ".4s", (outs V128:$dst),11966 (ins V128:$Rd, V128:$Rn, V128:$Rm),11967 [(set (v4i32 V128:$dst),11968 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn),11969 (v4i32 V128:$Rm)))]>;11970 11971class SHATiedInstQQV<bits<3> opc, string asm, Intrinsic OpNode>11972 : SHA3OpTiedInst<opc, asm, "", (outs FPR128:$dst),11973 (ins FPR128:$Rd, FPR128:$Rn, V128:$Rm),11974 [(set (v4i32 FPR128:$dst),11975 (OpNode (v4i32 FPR128:$Rd), (v4i32 FPR128:$Rn),11976 (v4i32 V128:$Rm)))]>;11977 11978let mayLoad = 0, mayStore = 0, hasSideEffects = 0 in11979class SHA2OpInst<bits<4> opc, string asm, string kind,11980 string cstr, dag oops, dag iops,11981 list<dag> pat>11982 : I<oops, iops, asm, "{\t$Rd" # kind # ", $Rn" # kind #11983 "|" # kind # "\t$Rd, $Rn}", cstr, pat>,11984 Sched<[WriteVq]>{11985 bits<5> Rd;11986 bits<5> Rn;11987 let Inst{31-16} = 0b0101111000101000;11988 let Inst{15-12} = opc;11989 let Inst{11-10} = 0b10;11990 let Inst{9-5} = Rn;11991 let Inst{4-0} = Rd;11992}11993 11994class SHATiedInstVV<bits<4> opc, string asm, Intrinsic OpNode>11995 : SHA2OpInst<opc, asm, ".4s", "$Rd = $dst", (outs V128:$dst),11996 (ins V128:$Rd, V128:$Rn),11997 [(set (v4i32 V128:$dst),11998 (OpNode (v4i32 V128:$Rd), (v4i32 V128:$Rn)))]>;11999 12000class SHAInstSS<bits<4> opc, string asm, Intrinsic OpNode>12001 : SHA2OpInst<opc, asm, "", "", (outs FPR32:$Rd), (ins FPR32:$Rn),12002 [(set (i32 FPR32:$Rd), (OpNode (i32 FPR32:$Rn)))]>;12003 12004// Armv8.2-A Crypto extensions12005class BaseCryptoV82<dag oops, dag iops, string asm, string asmops, string cst,12006 list<dag> pattern>12007 : I <oops, iops, asm, asmops, cst, pattern>, Sched<[WriteVq]> {12008 bits<5> Vd;12009 bits<5> Vn;12010 let Inst{31-25} = 0b1100111;12011 let Inst{9-5} = Vn;12012 let Inst{4-0} = Vd;12013}12014 12015class CryptoRRTied<bits<1>op0, bits<2>op1, string asm, string asmops>12016 : BaseCryptoV82<(outs V128:$Vdst), (ins V128:$Vd, V128:$Vn), asm, asmops,12017 "$Vd = $Vdst", []> {12018 let Inst{31-25} = 0b1100111;12019 let Inst{24-21} = 0b0110;12020 let Inst{20-15} = 0b000001;12021 let Inst{14} = op0;12022 let Inst{13-12} = 0b00;12023 let Inst{11-10} = op1;12024}12025class CryptoRRTied_2D<bits<1>op0, bits<2>op1, string asm>12026 : CryptoRRTied<op0, op1, asm, "{\t$Vd.2d, $Vn.2d|.2d\t$Vd, $Vn}">;12027class CryptoRRTied_4S<bits<1>op0, bits<2>op1, string asm>12028 : CryptoRRTied<op0, op1, asm, "{\t$Vd.4s, $Vn.4s|.4s\t$Vd, $Vn}">;12029 12030class CryptoRRR<bits<1> op0, bits<2>op1, dag oops, dag iops, string asm,12031 string asmops, string cst>12032 : BaseCryptoV82<oops, iops, asm , asmops, cst, []> {12033 bits<5> Vm;12034 let Inst{24-21} = 0b0011;12035 let Inst{20-16} = Vm;12036 let Inst{15} = 0b1;12037 let Inst{14} = op0;12038 let Inst{13-12} = 0b00;12039 let Inst{11-10} = op1;12040}12041class CryptoRRR_2D<bits<1> op0, bits<2>op1, string asm>12042 : CryptoRRR<op0, op1, (outs V128:$Vd), (ins V128:$Vn, V128:$Vm), asm,12043 "{\t$Vd.2d, $Vn.2d, $Vm.2d|.2d\t$Vd, $Vn, $Vm}", "">;12044class CryptoRRRTied_2D<bits<1> op0, bits<2>op1, string asm>12045 : CryptoRRR<op0, op1, (outs V128:$Vdst), (ins V128:$Vd, V128:$Vn, V128:$Vm), asm,12046 "{\t$Vd.2d, $Vn.2d, $Vm.2d|.2d\t$Vd, $Vn, $Vm}", "$Vd = $Vdst">;12047class CryptoRRR_4S<bits<1> op0, bits<2>op1, string asm>12048 : CryptoRRR<op0, op1, (outs V128:$Vd), (ins V128:$Vn, V128:$Vm), asm,12049 "{\t$Vd.4s, $Vn.4s, $Vm.4s|.4s\t$Vd, $Vn, $Vm}", "">;12050class CryptoRRRTied_4S<bits<1> op0, bits<2>op1, string asm>12051 : CryptoRRR<op0, op1, (outs V128:$Vdst), (ins V128:$Vd, V128:$Vn, V128:$Vm), asm,12052 "{\t$Vd.4s, $Vn.4s, $Vm.4s|.4s\t$Vd, $Vn, $Vm}", "$Vd = $Vdst">;12053class CryptoRRRTied<bits<1> op0, bits<2>op1, string asm>12054 : CryptoRRR<op0, op1, (outs FPR128:$Vdst), (ins FPR128:$Vd, FPR128:$Vn, V128:$Vm),12055 asm, "{\t$Vd, $Vn, $Vm.2d|.2d\t$Vd, $Vn, $Vm}", "$Vd = $Vdst">;12056 12057class CryptoRRRR<bits<2>op0, string asm, string asmops>12058 : BaseCryptoV82<(outs V128:$Vd), (ins V128:$Vn, V128:$Vm, V128:$Va), asm,12059 asmops, "", []> {12060 bits<5> Vm;12061 bits<5> Va;12062 let Inst{24-23} = 0b00;12063 let Inst{22-21} = op0;12064 let Inst{20-16} = Vm;12065 let Inst{15} = 0b0;12066 let Inst{14-10} = Va;12067}12068class CryptoRRRR_16B<bits<2>op0, string asm>12069 : CryptoRRRR<op0, asm, "{\t$Vd.16b, $Vn.16b, $Vm.16b, $Va.16b" #12070 "|.16b\t$Vd, $Vn, $Vm, $Va}"> {12071}12072class CryptoRRRR_4S<bits<2>op0, string asm>12073 : CryptoRRRR<op0, asm, "{\t$Vd.4s, $Vn.4s, $Vm.4s, $Va.4s" #12074 "|.4s\t$Vd, $Vn, $Vm, $Va}"> {12075}12076 12077class CryptoRRRi6<string asm>12078 : BaseCryptoV82<(outs V128:$Vd), (ins V128:$Vn, V128:$Vm, uimm6:$imm), asm,12079 "{\t$Vd.2d, $Vn.2d, $Vm.2d, $imm" #12080 "|.2d\t$Vd, $Vn, $Vm, $imm}", "", []> {12081 bits<6> imm;12082 bits<5> Vm;12083 let Inst{24-21} = 0b0100;12084 let Inst{20-16} = Vm;12085 let Inst{15-10} = imm;12086 let Inst{9-5} = Vn;12087 let Inst{4-0} = Vd;12088}12089 12090class CryptoRRRi2Tied<bits<1>op0, bits<2>op1, string asm>12091 : BaseCryptoV82<(outs V128:$Vdst),12092 (ins V128:$Vd, V128:$Vn, V128:$Vm, VectorIndexS:$imm),12093 asm, "{\t$Vd.4s, $Vn.4s, $Vm.s$imm" #12094 "|.4s\t$Vd, $Vn, $Vm$imm}", "$Vd = $Vdst", []> {12095 bits<2> imm;12096 bits<5> Vm;12097 let Inst{24-21} = 0b0010;12098 let Inst{20-16} = Vm;12099 let Inst{15} = 0b1;12100 let Inst{14} = op0;12101 let Inst{13-12} = imm;12102 let Inst{11-10} = op1;12103}12104 12105//----------------------------------------------------------------------------12106// v8.1 atomic instructions extension:12107// * CAS12108// * CASP12109// * SWP12110// * LDOPregister<OP>, and aliases STOPregister<OP>12111 12112// Instruction encodings:12113//12114// 31 30|29 24|23|22|21|20 16|15|14 10|9 5|4 012115// CAS SZ |001000|1 |A |1 |Rs |R |11111 |Rn |Rt12116// CASP 0|SZ|001000|0 |A |1 |Rs |R |11111 |Rn |Rt12117// SWP SZ |111000|A |R |1 |Rs |1 |OPC|00|Rn |Rt12118// LD SZ |111000|A |R |1 |Rs |0 |OPC|00|Rn |Rt12119// ST SZ |111000|A |R |1 |Rs |0 |OPC|00|Rn |1111112120 12121// Instruction syntax:12122//12123// CAS{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>]12124// CAS{<order>} <Xs>, <Xt>, [<Xn|SP>]12125// CASP{<order>} <Ws>, <W(s+1)>, <Wt>, <W(t+1)>, [<Xn|SP>]12126// CASP{<order>} <Xs>, <X(s+1)>, <Xt>, <X(t+1)>, [<Xn|SP>]12127// SWP{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>]12128// SWP{<order>} <Xs>, <Xt>, [<Xn|SP>]12129// LD<OP>{<order>}[<size>] <Ws>, <Wt>, [<Xn|SP>]12130// LD<OP>{<order>} <Xs>, <Xt>, [<Xn|SP>]12131// ST<OP>{<order>}[<size>] <Ws>, [<Xn|SP>]12132// ST<OP>{<order>} <Xs>, [<Xn|SP>]12133 12134let Predicates = [HasLSE], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in12135class BaseCASEncoding<dag oops, dag iops, string asm, string operands,12136 string cstr, list<dag> pattern>12137 : I<oops, iops, asm, operands, cstr, pattern> {12138 bits<2> Sz;12139 bit NP;12140 bit Acq;12141 bit Rel;12142 bits<5> Rs;12143 bits<5> Rn;12144 bits<5> Rt;12145 let Inst{31-30} = Sz;12146 let Inst{29-24} = 0b001000;12147 let Inst{23} = NP;12148 let Inst{22} = Acq;12149 let Inst{21} = 0b1;12150 let Inst{20-16} = Rs;12151 let Inst{15} = Rel;12152 let Inst{14-10} = 0b11111;12153 let Inst{9-5} = Rn;12154 let Inst{4-0} = Rt;12155 let Predicates = [HasLSE];12156}12157 12158class BaseCAS<string order, string size, RegisterClass RC>12159 : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn),12160 "cas" # order # size, "\t$Rs, $Rt, [$Rn]",12161 "$out = $Rs",[]>,12162 Sched<[WriteAtomic]> {12163 let NP = 1;12164}12165 12166multiclass CompareAndSwap<bits<1> Acq, bits<1> Rel, string order> {12167 let Sz = 0b00, Acq = Acq, Rel = Rel in def B : BaseCAS<order, "b", GPR32>;12168 let Sz = 0b01, Acq = Acq, Rel = Rel in def H : BaseCAS<order, "h", GPR32>;12169 let Sz = 0b10, Acq = Acq, Rel = Rel in def W : BaseCAS<order, "", GPR32>;12170 let Sz = 0b11, Acq = Acq, Rel = Rel in def X : BaseCAS<order, "", GPR64>;12171}12172 12173class BaseCASP<string order, string size, RegisterOperand RC>12174 : BaseCASEncoding<(outs RC:$out),(ins RC:$Rs, RC:$Rt, GPR64sp:$Rn),12175 "casp" # order # size, "\t$Rs, $Rt, [$Rn]",12176 "$out = $Rs",[]>,12177 Sched<[WriteAtomic]> {12178 let NP = 0;12179}12180 12181multiclass CompareAndSwapPair<bits<1> Acq, bits<1> Rel, string order> {12182 let Sz = 0b00, Acq = Acq, Rel = Rel in12183 def W : BaseCASP<order, "", WSeqPairClassOperand>;12184 let Sz = 0b01, Acq = Acq, Rel = Rel in12185 def X : BaseCASP<order, "", XSeqPairClassOperand>;12186}12187 12188// v9.6-a CAST unprivileged instructions12189let mayLoad = 1, mayStore = 1, hasSideEffects = 1 in12190class BaseCASTEncoding<dag oops, dag iops, string asm,12191 string cstr, list<dag> pattern>12192 : I<oops, iops, asm, "\t$Rs, $Rt, [$Rn]", cstr, pattern> {12193 bits<5> Rs;12194 bits<5> Rn;12195 bits<5> Rt;12196 bit L;12197 bit o0;12198 bits<2> Sz;12199 let Inst{31-30} = Sz;12200 let Inst{29-23} = 0b0010011;12201 let Inst{22} = L;12202 let Inst{21} = 0b0;12203 let Inst{20-16} = Rs;12204 let Inst{15} = o0;12205 let Inst{14-10} = 0b11111;12206 let Unpredictable{14-10} = 0b11111;12207 let Inst{9-5} = Rn;12208 let Inst{4-0} = Rt;12209}12210 12211multiclass CompareAndSwapUnprivileged<bits<2> Sz, bit L, bit o0, string order> {12212 let Sz = Sz, L = L, o0 = o0 in12213 def X : BaseCASTEncoding <12214 (outs GPR64:$out),12215 (ins GPR64:$Rs, GPR64:$Rt, GPR64sp0:$Rn),12216 "cas" # order # "t",12217 "$out = $Rs",[]>, Sched<[WriteAtomic]>;12218 12219}12220 12221multiclass CompareAndSwapPairUnprivileged<bits<2> Sz, bit L, bit o0, string order> {12222 let Sz = Sz, L = L, o0 = o0 in12223 def X : BaseCASTEncoding<(outs XSeqPairClassOperand:$out),12224 (ins XSeqPairClassOperand:$Rs, XSeqPairClassOperand:$Rt, GPR64sp0:$Rn),12225 "casp" # order # "t",12226 "$out = $Rs",[]>,12227 Sched<[WriteAtomic]>;12228}12229 12230let Predicates = [HasLSE] in12231class BaseSWP<string order, string size, RegisterClass RC>12232 : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "swp" # order # size,12233 "\t$Rs, $Rt, [$Rn]","",[]>,12234 Sched<[WriteAtomic]> {12235 bits<2> Sz;12236 bit Acq;12237 bit Rel;12238 bits<5> Rs;12239 bits<3> opc = 0b000;12240 bits<5> Rn;12241 bits<5> Rt;12242 let Inst{31-30} = Sz;12243 let Inst{29-24} = 0b111000;12244 let Inst{23} = Acq;12245 let Inst{22} = Rel;12246 let Inst{21} = 0b1;12247 let Inst{20-16} = Rs;12248 let Inst{15} = 0b1;12249 let Inst{14-12} = opc;12250 let Inst{11-10} = 0b00;12251 let Inst{9-5} = Rn;12252 let Inst{4-0} = Rt;12253 let Predicates = [HasLSE];12254}12255 12256multiclass Swap<bits<1> Acq, bits<1> Rel, string order> {12257 let Sz = 0b00, Acq = Acq, Rel = Rel in def B : BaseSWP<order, "b", GPR32>;12258 let Sz = 0b01, Acq = Acq, Rel = Rel in def H : BaseSWP<order, "h", GPR32>;12259 let Sz = 0b10, Acq = Acq, Rel = Rel in def W : BaseSWP<order, "", GPR32>;12260 let Sz = 0b11, Acq = Acq, Rel = Rel in def X : BaseSWP<order, "", GPR64>;12261}12262 12263// v9.6a swap operations12264class BaseSWPLSUI<string order, RegisterClass RC>12265 : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "swpt" # order,12266 "\t$Rs, $Rt, [$Rn]","",[]>,12267 Sched<[WriteAtomic]> {12268 bits<2> Sz;12269 bit Acq;12270 bit Rel;12271 bits<5> Rs;12272 bits<5> Rn;12273 bits<5> Rt;12274 let Inst{31-30} = Sz;12275 let Inst{29-24} = 0b011001;12276 let Inst{23} = Acq;12277 let Inst{22} = Rel;12278 let Inst{21} = 0b1;12279 let Inst{20-16} = Rs;12280 let Inst{15} = 0b1;12281 let Inst{14-12} = 0b000;12282 let Inst{11-10} = 0b01;12283 let Inst{9-5} = Rn;12284 let Inst{4-0} = Rt;12285}12286 12287multiclass SwapLSUI<bits<1> Acq, bits<1> Rel, string order> {12288 let Sz = 0b00, Acq = Acq, Rel = Rel in def W : BaseSWPLSUI<order, GPR32>;12289 let Sz = 0b01, Acq = Acq, Rel = Rel in def X : BaseSWPLSUI<order, GPR64>;12290}12291 12292let Predicates = [HasLSE], mayLoad = 1, mayStore = 1, hasSideEffects = 1 in12293class BaseLDOPregister<string op, string order, string size, RegisterClass RC>12294 : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "ld" # op # order # size,12295 "\t$Rs, $Rt, [$Rn]","",[]>,12296 Sched<[WriteAtomic]> {12297 bits<2> Sz;12298 bit Acq;12299 bit Rel;12300 bits<5> Rs;12301 bits<3> opc;12302 bits<5> Rn;12303 bits<5> Rt;12304 let Inst{31-30} = Sz;12305 let Inst{29-24} = 0b111000;12306 let Inst{23} = Acq;12307 let Inst{22} = Rel;12308 let Inst{21} = 0b1;12309 let Inst{20-16} = Rs;12310 let Inst{15} = 0b0;12311 let Inst{14-12} = opc;12312 let Inst{11-10} = 0b00;12313 let Inst{9-5} = Rn;12314 let Inst{4-0} = Rt;12315 let Predicates = [HasLSE];12316}12317 12318multiclass LDOPregister<bits<3> opc, string op, bits<1> Acq, bits<1> Rel,12319 string order> {12320 let Sz = 0b00, Acq = Acq, Rel = Rel, opc = opc in12321 def B : BaseLDOPregister<op, order, "b", GPR32>;12322 let Sz = 0b01, Acq = Acq, Rel = Rel, opc = opc in12323 def H : BaseLDOPregister<op, order, "h", GPR32>;12324 let Sz = 0b10, Acq = Acq, Rel = Rel, opc = opc in12325 def W : BaseLDOPregister<op, order, "", GPR32>;12326 let Sz = 0b11, Acq = Acq, Rel = Rel, opc = opc in12327 def X : BaseLDOPregister<op, order, "", GPR64>;12328}12329 12330class BaseLDOPregisterLSUI<string op, string order, RegisterClass RC>12331 : I<(outs RC:$Rt),(ins RC:$Rs, GPR64sp:$Rn), "ldt" # op # order,12332 "\t$Rs, $Rt, [$Rn]","",[]>,12333 Sched<[WriteAtomic]> {12334 bits<2> Sz;12335 bit Acq;12336 bit Rel;12337 bits<5> Rs;12338 bits<3> opc;12339 bits<5> Rn;12340 bits<5> Rt;12341 let Inst{31-30} = Sz;12342 let Inst{29-24} = 0b011001;12343 let Inst{23} = Acq;12344 let Inst{22} = Rel;12345 let Inst{21} = 0b1;12346 let Inst{20-16} = Rs;12347 let Inst{15} = 0b0;12348 let Inst{14-12} = opc;12349 let Inst{11-10} = 0b01;12350 let Inst{9-5} = Rn;12351 let Inst{4-0} = Rt;12352}12353 12354 12355multiclass LDOPregisterLSUI<bits<3> opc, string op, bits<1> Acq, bits<1> Rel,12356 string order> {12357 let Sz = 0b00, Acq = Acq, Rel = Rel, opc = opc in12358 def W : BaseLDOPregisterLSUI<op, order, GPR32>;12359 let Sz = 0b01, Acq = Acq, Rel = Rel, opc = opc in12360 def X : BaseLDOPregisterLSUI<op, order, GPR64>;12361}12362 12363// Differing SrcRHS and DstRHS allow you to cover CLR & SUB by giving a more12364// complex DAG for DstRHS.12365let Predicates = [HasLSE] in12366multiclass LDOPregister_patterns_ord_dag<string inst, string suffix, string op,12367 ValueType vt, dag SrcRHS, dag DstRHS> {12368 def : Pat<(!cast<PatFrag>(op#"_"#vt#"_monotonic") GPR64sp:$Rn, SrcRHS),12369 (!cast<Instruction>(inst # suffix) DstRHS, GPR64sp:$Rn)>;12370 def : Pat<(!cast<PatFrag>(op#"_"#vt#"_acquire") GPR64sp:$Rn, SrcRHS),12371 (!cast<Instruction>(inst # "A" # suffix) DstRHS, GPR64sp:$Rn)>;12372 def : Pat<(!cast<PatFrag>(op#"_"#vt#"_release") GPR64sp:$Rn, SrcRHS),12373 (!cast<Instruction>(inst # "L" # suffix) DstRHS, GPR64sp:$Rn)>;12374 def : Pat<(!cast<PatFrag>(op#"_"#vt#"_acq_rel") GPR64sp:$Rn, SrcRHS),12375 (!cast<Instruction>(inst # "AL" # suffix) DstRHS, GPR64sp:$Rn)>;12376 def : Pat<(!cast<PatFrag>(op#"_"#vt#"_seq_cst") GPR64sp:$Rn, SrcRHS),12377 (!cast<Instruction>(inst # "AL" # suffix) DstRHS, GPR64sp:$Rn)>;12378}12379 12380multiclass LDOPregister_patterns_ord<string inst, string suffix, string op,12381 ValueType vt, dag RHS> {12382 defm : LDOPregister_patterns_ord_dag<inst, suffix, op, vt, RHS, RHS>;12383}12384 12385multiclass LDOPregister_patterns_ord_mod<string inst, string suffix, string op,12386 ValueType vt, dag LHS, dag RHS> {12387 defm : LDOPregister_patterns_ord_dag<inst, suffix, op, vt, LHS, RHS>;12388}12389 12390multiclass LDOPregister_patterns<string inst, string op> {12391 defm : LDOPregister_patterns_ord<inst, "X", op, i64, (i64 GPR64:$Rm)>;12392 defm : LDOPregister_patterns_ord<inst, "W", op, i32, (i32 GPR32:$Rm)>;12393 defm : LDOPregister_patterns_ord<inst, "H", op, i16, (i32 GPR32:$Rm)>;12394 defm : LDOPregister_patterns_ord<inst, "B", op, i8, (i32 GPR32:$Rm)>;12395}12396 12397multiclass LDOPregister_patterns_mod<string inst, string op, string mod> {12398 defm : LDOPregister_patterns_ord_mod<inst, "X", op, i64,12399 (i64 GPR64:$Rm),12400 (i64 (!cast<Instruction>(mod#Xrr) XZR, GPR64:$Rm))>;12401 defm : LDOPregister_patterns_ord_mod<inst, "W", op, i32,12402 (i32 GPR32:$Rm),12403 (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>;12404 defm : LDOPregister_patterns_ord_mod<inst, "H", op, i16,12405 (i32 GPR32:$Rm),12406 (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>;12407 defm : LDOPregister_patterns_ord_mod<inst, "B", op, i8,12408 (i32 GPR32:$Rm),12409 (i32 (!cast<Instruction>(mod#Wrr) WZR, GPR32:$Rm))>;12410}12411 12412let Predicates = [HasLSFE] in12413multiclass LDFPOPregister_patterns_ord_dag<string inst, string suffix, string op,12414 ValueType vt, dag data> {12415 def : Pat<(!cast<PatFrag>(op#"_"#vt#"_monotonic") FPR64:$Rn, data),12416 (!cast<Instruction>(inst # suffix) data, FPR64:$Rn)>;12417 def : Pat<(!cast<PatFrag>(op#"_"#vt#"_acquire") FPR64:$Rn, data),12418 (!cast<Instruction>(inst # "A" # suffix) data, FPR64:$Rn)>;12419 def : Pat<(!cast<PatFrag>(op#"_"#vt#"_release") FPR64:$Rn, data),12420 (!cast<Instruction>(inst # "L" # suffix) data, FPR64:$Rn)>;12421 def : Pat<(!cast<PatFrag>(op#"_"#vt#"_acq_rel") FPR64:$Rn, data),12422 (!cast<Instruction>(inst # "AL" # suffix) data, FPR64:$Rn)>;12423 def : Pat<(!cast<PatFrag>(op#"_"#vt#"_seq_cst") FPR64:$Rn, data),12424 (!cast<Instruction>(inst # "AL" # suffix) data, FPR64:$Rn)>;12425}12426 12427multiclass LDFPOPregister_patterns_ord<string inst, string suffix, string op,12428 ValueType vt, dag RHS> {12429 defm : LDFPOPregister_patterns_ord_dag<inst, suffix, op, vt, RHS>;12430}12431 12432multiclass LDFPOPregister_patterns<string inst, string op> {12433 defm : LDFPOPregister_patterns_ord<inst, "H", op, f16, (f16 FPR16:$Rm)>;12434 defm : LDFPOPregister_patterns_ord<inst, "S", op, f32, (f32 FPR32:$Rm)>;12435 defm : LDFPOPregister_patterns_ord<inst, "D", op, f64, (f64 FPR64:$Rm)>;12436}12437 12438multiclass LDBFPOPregister_patterns<string inst, string op> {12439 defm : LDFPOPregister_patterns_ord<inst, "", op, bf16, (bf16 FPR16:$Rm)>;12440}12441 12442let Predicates = [HasLSE] in12443multiclass CASregister_patterns_ord_dag<string inst, string suffix, string op,12444 ValueType vt, dag OLD, dag NEW> {12445 def : Pat<(!cast<PatFrag>(op#"_"#vt#"_monotonic") GPR64sp:$Rn, OLD, NEW),12446 (!cast<Instruction>(inst # suffix) OLD, NEW, GPR64sp:$Rn)>;12447 def : Pat<(!cast<PatFrag>(op#"_"#vt#"_acquire") GPR64sp:$Rn, OLD, NEW),12448 (!cast<Instruction>(inst # "A" # suffix) OLD, NEW, GPR64sp:$Rn)>;12449 def : Pat<(!cast<PatFrag>(op#"_"#vt#"_release") GPR64sp:$Rn, OLD, NEW),12450 (!cast<Instruction>(inst # "L" # suffix) OLD, NEW, GPR64sp:$Rn)>;12451 def : Pat<(!cast<PatFrag>(op#"_"#vt#"_acq_rel") GPR64sp:$Rn, OLD, NEW),12452 (!cast<Instruction>(inst # "AL" # suffix) OLD, NEW, GPR64sp:$Rn)>;12453 def : Pat<(!cast<PatFrag>(op#"_"#vt#"_seq_cst") GPR64sp:$Rn, OLD, NEW),12454 (!cast<Instruction>(inst # "AL" # suffix) OLD, NEW, GPR64sp:$Rn)>;12455}12456 12457multiclass CASregister_patterns_ord<string inst, string suffix, string op,12458 ValueType vt, dag OLD, dag NEW> {12459 defm : CASregister_patterns_ord_dag<inst, suffix, op, vt, OLD, NEW>;12460}12461 12462multiclass CASregister_patterns<string inst, string op> {12463 defm : CASregister_patterns_ord<inst, "X", op, i64,12464 (i64 GPR64:$Rold), (i64 GPR64:$Rnew)>;12465 defm : CASregister_patterns_ord<inst, "W", op, i32,12466 (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>;12467 defm : CASregister_patterns_ord<inst, "H", op, i16,12468 (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>;12469 defm : CASregister_patterns_ord<inst, "B", op, i8,12470 (i32 GPR32:$Rold), (i32 GPR32:$Rnew)>;12471}12472 12473let Predicates = [HasLSE] in12474class BaseSTOPregister<string asm, RegisterClass OP, Register Reg,12475 Instruction inst> :12476 InstAlias<asm # "\t$Rs, [$Rn]", (inst Reg, OP:$Rs, GPR64sp:$Rn)>;12477 12478multiclass STOPregister<string asm, string instr> {12479 def : BaseSTOPregister<asm # "lb", GPR32, WZR,12480 !cast<Instruction>(instr # "LB")>;12481 def : BaseSTOPregister<asm # "lh", GPR32, WZR,12482 !cast<Instruction>(instr # "LH")>;12483 def : BaseSTOPregister<asm # "l", GPR32, WZR,12484 !cast<Instruction>(instr # "LW")>;12485 def : BaseSTOPregister<asm # "l", GPR64, XZR,12486 !cast<Instruction>(instr # "LX")>;12487 def : BaseSTOPregister<asm # "b", GPR32, WZR,12488 !cast<Instruction>(instr # "B")>;12489 def : BaseSTOPregister<asm # "h", GPR32, WZR,12490 !cast<Instruction>(instr # "H")>;12491 def : BaseSTOPregister<asm, GPR32, WZR,12492 !cast<Instruction>(instr # "W")>;12493 def : BaseSTOPregister<asm, GPR64, XZR,12494 !cast<Instruction>(instr # "X")>;12495}12496 12497let Predicates = [HasLSUI] in12498class BaseSTOPregisterLSUI<string asm, RegisterClass OP, Register Reg,12499 Instruction inst> :12500 InstAlias<asm # "\t$Rs, [$Rn]", (inst Reg, OP:$Rs, GPR64sp:$Rn)>;12501 12502multiclass STOPregisterLSUI<string asm, string instr> {12503 def : BaseSTOPregisterLSUI<asm # "l", GPR32, WZR,12504 !cast<Instruction>(instr # "LW")>;12505 def : BaseSTOPregisterLSUI<asm # "l", GPR64, XZR,12506 !cast<Instruction>(instr # "LX")>;12507 def : BaseSTOPregisterLSUI<asm, GPR32, WZR,12508 !cast<Instruction>(instr # "W")>;12509 def : BaseSTOPregisterLSUI<asm, GPR64, XZR,12510 !cast<Instruction>(instr # "X")>;12511}12512 12513class LoadStore64B_base<bits<3> opc, string asm_inst, string asm_ops,12514 dag iops, dag oops, list<dag> pat>12515 : I<oops, iops, asm_inst, asm_ops, "", pat>,12516 Sched<[]> /* FIXME: fill in scheduling details once known */ {12517 bits<5> Rt;12518 bits<5> Rn;12519 let Inst{31-21} = 0b11111000001;12520 let Inst{15} = 1;12521 let Inst{14-12} = opc;12522 let Inst{11-10} = 0b00;12523 let Inst{9-5} = Rn;12524 let Inst{4-0} = Rt;12525 12526 let Predicates = [HasV8_7a];12527}12528 12529class LoadStore64B<bits<3> opc, string asm_inst, dag iops, dag oops,12530 list<dag> pat = []>12531 : LoadStore64B_base<opc, asm_inst, "\t$Rt, [$Rn]", iops, oops, pat> {12532 let Inst{20-16} = 0b11111;12533}12534 12535class Store64BV<bits<3> opc, string asm_inst, list<dag> pat = []>12536 : LoadStore64B_base<opc, asm_inst, "\t$Rs, $Rt, [$Rn]",12537 (ins GPR64x8:$Rt, GPR64sp:$Rn), (outs GPR64:$Rs), pat> {12538 bits<5> Rs;12539 let Inst{20-16} = Rs;12540 let mayStore = 1;12541}12542 12543class MOPSMemoryCopyMoveBase<bit isMove, bits<2> opcode, bits<2> op1,12544 bits<2> op2, string asm>12545 : I<(outs GPR64common:$Rd_wb, GPR64common:$Rs_wb, GPR64:$Rn_wb),12546 (ins GPR64common:$Rd, GPR64common:$Rs, GPR64:$Rn),12547 asm, "\t[$Rd]!, [$Rs]!, $Rn!",12548 "$Rd = $Rd_wb,$Rs = $Rs_wb,$Rn = $Rn_wb", []>,12549 Sched<[]> {12550 bits<5> Rd;12551 bits<5> Rs;12552 bits<5> Rn;12553 let Inst{31-27} = 0b00011;12554 let Inst{26} = isMove;12555 let Inst{25-24} = 0b01;12556 let Inst{23-22} = opcode;12557 let Inst{21} = 0b0;12558 let Inst{20-16} = Rs;12559 let Inst{15-14} = op2;12560 let Inst{13-12} = op1;12561 let Inst{11-10} = 0b01;12562 let Inst{9-5} = Rn;12563 let Inst{4-0} = Rd;12564 12565 let DecoderMethod = "DecodeCPYMemOpInstruction";12566 let mayLoad = 1;12567 let mayStore = 1;12568}12569 12570class MOPSMemoryCopy<bits<2> opcode, bits<2> op1, bits<2> op2, string asm>12571 : MOPSMemoryCopyMoveBase<0, opcode, op1, op2, asm>;12572 12573class MOPSMemoryMove<bits<2> opcode, bits<2> op1, bits<2> op2, string asm>12574 : MOPSMemoryCopyMoveBase<1, opcode, op1, op2, asm>;12575 12576class MOPSMemorySetBase<dag ins, string operands, bit isTagging, bits<2> opcode,12577 bit op1, bit op2, bit op3, string asm>12578 : I<(outs GPR64common:$Rd_wb, GPR64:$Rn_wb), ins,12579 asm, operands, "$Rd = $Rd_wb,$Rn = $Rn_wb", []>,12580 Sched<[]> {12581 bits<5> Rd;12582 bits<5> Rn;12583 bits<5> Rm;12584 let Inst{31-27} = 0b00011;12585 let Inst{26} = isTagging;12586 let Inst{25-21} = 0b01110;12587 let Inst{20-16} = Rm;12588 let Inst{15-14} = opcode;12589 let Inst{13} = op2;12590 let Inst{12} = op1;12591 let Inst{11} = 0b0;12592 let Inst{10} = op3;12593 let Inst{9-5} = Rn;12594 let Inst{4-0} = Rd;12595 12596 let mayLoad = 0;12597 let mayStore = 1;12598}12599 12600class MOPSMemorySet<bits<2> opcode, bit op1, bit op2, bit op3, string asm>12601 : MOPSMemorySetBase<(ins GPR64common:$Rd, GPR64:$Rn, GPR64:$Rm),12602 "\t[$Rd]!, $Rn!, $Rm", 0, opcode, op1, op2, op3, asm> {12603 let DecoderMethod = "DecodeSETMemOpInstruction";12604}12605 12606class MOPSMemorySetTagging<bits<2> opcode, bit op1, bit op2, bit op3, string asm>12607 : MOPSMemorySetBase<(ins GPR64common:$Rd, GPR64:$Rn, GPR64:$Rm),12608 "\t[$Rd]!, $Rn!, $Rm", 1, opcode, op1, op2, op3, asm> {12609 let DecoderMethod = "DecodeSETMemOpInstruction";12610}12611 12612class MOPSGoMemorySetTagging<bits<2> opcode, bit op1, bit op2, bit op3, string asm>12613 : MOPSMemorySetBase<(ins GPR64common:$Rd, GPR64:$Rn),12614 "\t[$Rd]!, $Rn!", 1, opcode, op1, op2, op3, asm> {12615 // No `Rm` operand, as all bits must be set to 112616 let Inst{20-16} = 0b11111;12617 let DecoderMethod = "DecodeSETMemGoOpInstruction";12618}12619 12620multiclass MOPSMemoryCopyInsns<bits<2> opcode, string asm> {12621 def "" : MOPSMemoryCopy<opcode, 0b00, 0b00, asm>;12622 def WN : MOPSMemoryCopy<opcode, 0b00, 0b01, asm # "wn">;12623 def RN : MOPSMemoryCopy<opcode, 0b00, 0b10, asm # "rn">;12624 def N : MOPSMemoryCopy<opcode, 0b00, 0b11, asm # "n">;12625 def WT : MOPSMemoryCopy<opcode, 0b01, 0b00, asm # "wt">;12626 def WTWN : MOPSMemoryCopy<opcode, 0b01, 0b01, asm # "wtwn">;12627 def WTRN : MOPSMemoryCopy<opcode, 0b01, 0b10, asm # "wtrn">;12628 def WTN : MOPSMemoryCopy<opcode, 0b01, 0b11, asm # "wtn">;12629 def RT : MOPSMemoryCopy<opcode, 0b10, 0b00, asm # "rt">;12630 def RTWN : MOPSMemoryCopy<opcode, 0b10, 0b01, asm # "rtwn">;12631 def RTRN : MOPSMemoryCopy<opcode, 0b10, 0b10, asm # "rtrn">;12632 def RTN : MOPSMemoryCopy<opcode, 0b10, 0b11, asm # "rtn">;12633 def T : MOPSMemoryCopy<opcode, 0b11, 0b00, asm # "t">;12634 def TWN : MOPSMemoryCopy<opcode, 0b11, 0b01, asm # "twn">;12635 def TRN : MOPSMemoryCopy<opcode, 0b11, 0b10, asm # "trn">;12636 def TN : MOPSMemoryCopy<opcode, 0b11, 0b11, asm # "tn">;12637}12638 12639multiclass MOPSMemoryMoveInsns<bits<2> opcode, string asm> {12640 def "" : MOPSMemoryMove<opcode, 0b00, 0b00, asm>;12641 def WN : MOPSMemoryMove<opcode, 0b00, 0b01, asm # "wn">;12642 def RN : MOPSMemoryMove<opcode, 0b00, 0b10, asm # "rn">;12643 def N : MOPSMemoryMove<opcode, 0b00, 0b11, asm # "n">;12644 def WT : MOPSMemoryMove<opcode, 0b01, 0b00, asm # "wt">;12645 def WTWN : MOPSMemoryMove<opcode, 0b01, 0b01, asm # "wtwn">;12646 def WTRN : MOPSMemoryMove<opcode, 0b01, 0b10, asm # "wtrn">;12647 def WTN : MOPSMemoryMove<opcode, 0b01, 0b11, asm # "wtn">;12648 def RT : MOPSMemoryMove<opcode, 0b10, 0b00, asm # "rt">;12649 def RTWN : MOPSMemoryMove<opcode, 0b10, 0b01, asm # "rtwn">;12650 def RTRN : MOPSMemoryMove<opcode, 0b10, 0b10, asm # "rtrn">;12651 def RTN : MOPSMemoryMove<opcode, 0b10, 0b11, asm # "rtn">;12652 def T : MOPSMemoryMove<opcode, 0b11, 0b00, asm # "t">;12653 def TWN : MOPSMemoryMove<opcode, 0b11, 0b01, asm # "twn">;12654 def TRN : MOPSMemoryMove<opcode, 0b11, 0b10, asm # "trn">;12655 def TN : MOPSMemoryMove<opcode, 0b11, 0b11, asm # "tn">;12656}12657 12658multiclass MOPSMemorySetInsns<bits<2> opcode, string asm> {12659 def "" : MOPSMemorySet<opcode, 0, 0, 1, asm>;12660 def T : MOPSMemorySet<opcode, 1, 0, 1, asm # "t">;12661 def N : MOPSMemorySet<opcode, 0, 1, 1, asm # "n">;12662 def TN : MOPSMemorySet<opcode, 1, 1, 1, asm # "tn">;12663}12664 12665multiclass MOPSMemorySetTaggingInsns<bits<2> opcode, string asm> {12666 def "" : MOPSMemorySetTagging<opcode, 0, 0, 1, asm>;12667 def T : MOPSMemorySetTagging<opcode, 1, 0, 1, asm # "t">;12668 def N : MOPSMemorySetTagging<opcode, 0, 1, 1, asm # "n">;12669 def TN : MOPSMemorySetTagging<opcode, 1, 1, 1, asm # "tn">;12670}12671 12672//----------------------------------------------------------------------------12673// MOPS Granule Only - FEAT_MOPS_GO12674//----------------------------------------------------------------------------12675multiclass MOPSGoMemorySetTaggingInsns<bits<2> opcode, string asm> {12676 def "" : MOPSGoMemorySetTagging<opcode, 0, 0, 0, asm>;12677 def T : MOPSGoMemorySetTagging<opcode, 1, 0, 0, asm # "t">;12678 def N : MOPSGoMemorySetTagging<opcode, 0, 1, 0, asm # "n">;12679 def TN : MOPSGoMemorySetTagging<opcode, 1, 1, 0, asm # "tn">;12680}12681 12682//----------------------------------------------------------------------------12683// 2022 Armv8.9/Armv9.4 Extensions12684//----------------------------------------------------------------------------12685 12686//---12687// 2022 Architecture Extensions: General Data Processing (FEAT_CSSC)12688//---12689 12690class BaseTwoOperandRegImm<bit sf, bit Op, bit S, bits<4> opc,12691 RegisterClass regtype, ImmLeaf immtype, string asm,12692 SDPatternOperator OpNode>12693 : I<(outs regtype:$Rd), (ins regtype:$Rn, immtype:$imm),12694 asm, "\t$Rd, $Rn, $imm", "",12695 [(set regtype:$Rd, (OpNode regtype:$Rn, immtype:$imm))]> {12696 bits<5> Rd;12697 bits<5> Rn;12698 bits<8> imm;12699 12700 let Inst{31} = sf;12701 let Inst{30} = Op;12702 let Inst{29} = S;12703 let Inst{28-22} = 0b1000111;12704 let Inst{21-18} = opc;12705 let Inst{17-10} = imm;12706 let Inst{9-5} = Rn;12707 let Inst{4-0} = Rd;12708}12709 12710class BaseComparisonOpReg<bit size, bit isUnsigned, bit isMin,12711 RegisterClass regtype, string asm,12712 SDPatternOperator OpNode>12713 : BaseTwoOperandRegReg<size, 0b0, {0,1,1,0,?,?}, regtype, asm, OpNode>,12714 Sched<[WriteI]> {12715 let Inst{11} = isMin;12716 let Inst{10} = isUnsigned;12717 let mayLoad = 0;12718 let mayStore = 0;12719 let hasSideEffects = 0;12720}12721 12722class BaseComparisonOpImm<bit size, bit isUnsigned, bit isMin,12723 RegisterClass regtype, ImmLeaf immtype, string asm,12724 SDPatternOperator OpNode>12725 : BaseTwoOperandRegImm<size, 0b0, 0b0, {0,0,?,?}, regtype, immtype, asm,12726 OpNode>,12727 Sched<[]> {12728 let Inst{19} = isMin;12729 let Inst{18} = isUnsigned;12730 let mayLoad = 0;12731 let mayStore = 0;12732 let hasSideEffects = 0;12733}12734 12735multiclass ComparisonOp<bit isUnsigned, bit isMin, string asm,12736 SDPatternOperator OpNode = null_frag> {12737 def Wrr : BaseComparisonOpReg<0b0, isUnsigned, isMin, GPR32, asm, OpNode>;12738 12739 def Wri : BaseComparisonOpImm<0b0, isUnsigned, isMin, GPR32,12740 !cond(isUnsigned : uimm8_32b,12741 !not(isUnsigned) : simm8_32b), asm, OpNode>;12742 12743 def Xrr : BaseComparisonOpReg<0b1, isUnsigned, isMin, GPR64, asm, OpNode>;12744 12745 def Xri : BaseComparisonOpImm<0b1, isUnsigned, isMin, GPR64,12746 !cond(isUnsigned : uimm8_64b,12747 !not(isUnsigned) : simm8_64b), asm, OpNode>;12748}12749 12750//---12751// RCPC instructions (FEAT_LRCPC3)12752//---12753 12754class BaseLRCPC3<bits<2> size, bit V, bits<2> opc, dag oops, dag iops,12755 string asm, string operands, string cstr = "">12756 : I<oops, iops, asm, operands, cstr, []>,12757 Sched<[WriteAtomic]> {12758 bits<5> Rt;12759 bits<5> Rn;12760 let Inst{31-30} = size;12761 let Inst{29-24} = {0,1,1,V,0,1};12762 let Inst{23-22} = opc;12763 let Inst{21} = 0b0;12764 // Inst{20-12}12765 let Inst{11-10} = 0b10;12766 let Inst{9-5} = Rn;12767 let Inst{4-0} = Rt;12768 12769 let mayLoad = Inst{22};12770 let mayStore = !not(Inst{22});12771 let hasSideEffects = 0;12772}12773 12774class BaseLRCPC3IntegerLoadStorePair<bits<2> size, bits<2> opc, bits<4> opc2,12775 dag oops, dag iops, string asm,12776 string operands, string cstr>12777 : BaseLRCPC3<size, /*V*/0, opc, oops, iops, asm, operands, cstr> {12778 bits<5> Rt2;12779 let Inst{20-16} = Rt2;12780 let Inst{15-12} = opc2;12781}12782 12783class BaseLRCPC3IntegerLoadStore<bits<2> size, bits<2> opc, dag oops, dag iops,12784 string asm, string operands, string cstr>12785 : BaseLRCPC3<size, /*V*/0, opc, oops, iops, asm, operands, cstr> {12786 let Inst{20-12} = 0b000000000; // imm912787}12788 12789multiclass LRCPC3NEONLoadStoreUnscaledOffset<bits<2> size, bits<2> opc, RegisterClass regtype,12790 dag oops, dag iops, string asm> {12791 def i : BaseLRCPC3<size, /*V*/1, opc, oops, iops, asm, "\t$Rt, [$Rn{, $simm}]", /*cstr*/""> {12792 bits<9> simm; // signed immediate encoded in imm9=Rt2:imm412793 let Inst{20-12} = simm;12794 }12795 12796 def a : InstAlias<asm # "\t$Rt, [$Rn]",12797 (!cast<Instruction>(NAME # "i") regtype:$Rt, GPR64sp:$Rn, 0)>;12798}12799 12800class LRCPC3NEONLdStSingle<bit L, dag oops, dag iops, string asm, string cst>12801 : BaseSIMDLdStSingle<L, /*R*/0b0, /*opcode*/0b100, asm,12802 "\t$Vt$Q, [$Rn]", cst, oops, iops, []>,12803 Sched<[]> {12804 bit Q;12805 let Inst{31} = 0;12806 let Inst{30} = Q;12807 let Inst{23} = 0;12808 let Inst{20-16} = 0b00001;12809 let Inst{12} = 0; // S12810 let Inst{11-10} = 0b01; // size12811 12812 let mayLoad = L;12813 let mayStore = !not(L);12814 let hasSideEffects = 1;12815}12816 12817//---12818// Instrumentation Extension (FEAT_ITE)12819//---12820 12821let Predicates = [HasITE] in12822def TRCIT : RtSystemI<0b0, (outs), (ins GPR64:$Rt), "trcit", "\t$Rt"> {12823 let Inst{20-19} = 0b01;12824 let Inst{18-16} = 0b011;12825 let Inst{15-12} = 0b0111;12826 let Inst{11-8} = 0b0010;12827 let Inst{7-5} = 0b111;12828}12829 12830// * RCWCAS family12831// * RCW<OP> family12832 12833//--------------------------------------------------------------------12834// Read-Check-Write Compare And Swap family (RCWCAS[S|P|PS]?[A|L|AL]?)12835 12836// Instruction encoding:12837//12838// 31 30|29 24|23|22|21|20 16|15|14 13|12 11 10|9 5|4 012839// RCWCAS 0 0|011001| A| R| 1| Rs| 0| 0 0| 0 1 0| Rn| Rt12840// RCWSCAS 0 1|011001| A| R| 1| Rs| 0| 0 0| 0 1 0| Rn| Rt12841// RCWCASP 0 0|011001| A| R| 1| Rs| 0| 0 0| 0 1 1| Rn| Rt12842// RCWSCASP 0 1|011001| A| R| 1| Rs| 0| 0 0| 0 1 1| Rn| Rt12843 12844// Instruction syntax:12845//12846// RCW[S]CAS{<order>} <Xs>, <Xt>, [<Xn|SP>]12847// RCW[S]CASP{<order>} <Xs>, <X(s+1)>, <Xt>, <X(t+1)> [<Xn|SP>]12848 12849class BaseRCWCASEncoding<dag oops, dag iops, string asm>12850 : I<oops, iops, asm, "\t$Rs, $Rt, [$Rn]", "$out = $Rs", []>,12851 Sched<[]> {12852 bit Acq;12853 bit Rel;12854 bit SC;12855 bit Pair;12856 bits<5> Rs;12857 bits<5> Rn;12858 bits<5> Rt;12859 let Inst{31} = 0b0;12860 let Inst{30} = SC;12861 let Inst{29-24} = 0b011001;12862 let Inst{23} = Acq;12863 let Inst{22} = Rel;12864 let Inst{21} = 0b1;12865 let Inst{20-16} = Rs;12866 let Inst{15-13} = 0b000;12867 let Inst{12-11} = 0b01;12868 let Inst{10} = Pair;12869 let Inst{9-5} = Rn;12870 let Inst{4-0} = Rt;12871 let mayLoad = 1;12872 let mayStore = 1;12873 let hasSideEffects = 1;12874 let Defs = [NZCV];12875}12876 12877multiclass BaseRCWCAS<dag oops, dag iops, string prefix> {12878 let Acq = 0b0, Rel = 0b0 in12879 def "" : BaseRCWCASEncoding<oops, iops, prefix # "">;12880 let Acq = 0b1, Rel = 0b0 in12881 def A : BaseRCWCASEncoding<oops, iops, prefix # "a">;12882 let Acq = 0b0, Rel = 0b1 in12883 def L : BaseRCWCASEncoding<oops, iops, prefix # "l">;12884 let Acq = 0b1, Rel = 0b1 in12885 def AL : BaseRCWCASEncoding<oops, iops, prefix # "al">;12886}12887 12888multiclass ReadCheckWriteCompareAndSwap {12889 let SC = 0b0, Pair = 0b0, Predicates = [HasTHE] in12890 defm CAS : BaseRCWCAS<(outs GPR64:$out),12891 (ins GPR64:$Rs, GPR64:$Rt, GPR64sp:$Rn), "rcwcas" >;12892 let SC = 0b1, Pair = 0b0, Predicates = [HasTHE] in12893 defm SCAS : BaseRCWCAS<(outs GPR64:$out),12894 (ins GPR64:$Rs, GPR64:$Rt, GPR64sp:$Rn), "rcwscas">;12895 let SC = 0b0, Pair = 0b1, Predicates = [HasTHE, HasD128] in12896 defm CASP : BaseRCWCAS<(outs XSeqPairClassOperand:$out),12897 (ins XSeqPairClassOperand:$Rs,12898 XSeqPairClassOperand:$Rt, GPR64sp:$Rn),12899 "rcwcasp">;12900 let SC = 0b1, Pair = 0b1, Predicates = [HasTHE, HasD128] in12901 defm SCASP: BaseRCWCAS<(outs XSeqPairClassOperand:$out),12902 (ins XSeqPairClassOperand:$Rs,12903 XSeqPairClassOperand:$Rt, GPR64sp:$Rn),12904 "rcwscasp">;12905}12906 12907//------------------------------------------------------------------12908// Read-Check-Write <OP> family (RCW[CLR|SET|SWP][S|P|PS]?[A|L|AL]?)12909 12910// Instruction encoding:12911//12912// 31 30|29 24|23|22|21|20 16|15|14 12|11 10|9 5|4 012913// RCWCLR 0 0|111000| A| R| 1| Rs| 1| 001| 0 0| Rn| Rt12914// RCWSCLR 0 1|111000| A| R| 1| Rs| 1| 001| 0 0| Rn| Rt12915// RCWSET 0 0|111000| A| R| 1| Rs| 1| 011| 0 0| Rn| Rt12916// RCWSSET 0 1|111000| A| R| 1| Rs| 1| 011| 0 0| Rn| Rt12917// RCWSWP 0 0|111000| A| R| 1| Rs| 1| 010| 0 0| Rn| Rt12918// RCWSSWP 0 1|111000| A| R| 1| Rs| 1| 010| 0 0| Rn| Rt12919 12920// 31 30|29 24|23|22|21|20 16|15|14 12|11 10|9 5|4 012921// RCWCLRP 0 0|011001| A| R| 1| Rt2| 1| 001| 0 0| Rn| Rt12922// RCWSCLRP 0 1|011001| A| R| 1| Rt2| 1| 001| 0 0| Rn| Rt12923// RCWSETP 0 0|011001| A| R| 1| Rt2| 1| 011| 0 0| Rn| Rt12924// RCWSSETP 0 1|011001| A| R| 1| Rt2| 1| 011| 0 0| Rn| Rt12925// RCWSWPP 0 0|011001| A| R| 1| Rt2| 1| 010| 0 0| Rn| Rt12926// RCWSSWPP 0 1|011001| A| R| 1| Rt2| 1| 010| 0 0| Rn| Rt12927 12928// Instruction syntax:12929//12930// RCW[S]<OP>{<order>} <Xs>, <Xt>, [<Xn|SP>]12931// RCW[S]<OP>P{<order>} <Xt1>, <Xt2>, [<Xn|SP>]12932 12933class BaseRCWOPEncoding<string asm>12934 : I<(outs GPR64:$Rt),(ins GPR64:$Rs, GPR64sp:$Rn), asm,12935 "\t$Rs, $Rt, [$Rn]", "", []>,12936 Sched<[]> {12937 bit Acq;12938 bit Rel;12939 bit SC;12940 bits<3> opc;12941 bits<5> Rs;12942 bits<5> Rn;12943 bits<5> Rt;12944 let Inst{31} = 0b0;12945 let Inst{30} = SC;12946 let Inst{29-24} = 0b111000;12947 let Inst{23} = Acq;12948 let Inst{22} = Rel;12949 let Inst{21} = 0b1;12950 let Inst{20-16} = Rs;12951 let Inst{15} = 0b1;12952 let Inst{14-12} = opc;12953 let Inst{11-10} = 0b00;12954 let Inst{9-5} = Rn;12955 let Inst{4-0} = Rt;12956 let mayLoad = 1;12957 let mayStore = 1;12958 let hasSideEffects = 1;12959 let Defs = [NZCV];12960 let Predicates = [HasTHE];12961}12962 12963class BaseRCWOPPEncoding<string asm>12964 : I<(outs GPR64common:$Rt_wb, GPR64common:$Rt2_wb),12965 (ins GPR64common:$Rt, GPR64common:$Rt2, GPR64sp:$Rn), asm,12966 "\t$Rt, $Rt2, [$Rn]", "$Rt = $Rt_wb, $Rt2 = $Rt2_wb", []>,12967 Sched<[]> {12968 bit Acq;12969 bit Rel;12970 bit SC;12971 bits<3> opc;12972 bits<5> Rt2;12973 bits<5> Rn;12974 bits<5> Rt;12975 let Inst{31} = 0b0;12976 let Inst{30} = SC;12977 let Inst{29-24} = 0b011001;12978 let Inst{23} = Acq;12979 let Inst{22} = Rel;12980 let Inst{21} = 0b1;12981 let Inst{20-16} = Rt2;12982 let Inst{15} = 0b1;12983 let Inst{14-12} = opc;12984 let Inst{11-10} = 0b00;12985 let Inst{9-5} = Rn;12986 let Inst{4-0} = Rt;12987 let mayLoad = 1;12988 let mayStore = 1;12989 let hasSideEffects = 1;12990 let Defs = [NZCV];12991 let Predicates = [HasTHE, HasD128];12992}12993 12994multiclass BaseRCWOP<string prefix> {12995 let Acq = 0b0, Rel = 0b0 in def "" : BaseRCWOPEncoding<prefix # "">;12996 let Acq = 0b1, Rel = 0b0 in def A : BaseRCWOPEncoding<prefix # "a">;12997 let Acq = 0b0, Rel = 0b1 in def L : BaseRCWOPEncoding<prefix # "l">;12998 let Acq = 0b1, Rel = 0b1 in def AL : BaseRCWOPEncoding<prefix # "al">;12999 13000 let Acq = 0b0, Rel = 0b0 in def P : BaseRCWOPPEncoding<prefix # "p">;13001 let Acq = 0b1, Rel = 0b0 in def PA : BaseRCWOPPEncoding<prefix # "pa">;13002 let Acq = 0b0, Rel = 0b1 in def PL : BaseRCWOPPEncoding<prefix # "pl">;13003 let Acq = 0b1, Rel = 0b1 in def PAL : BaseRCWOPPEncoding<prefix # "pal">;13004}13005 13006multiclass ReadCheckWriteOperation<bits<3> opc, string op> {13007 let SC = 0b0, opc = opc in defm "" : BaseRCWOP<"rcw" # "" # op>;13008 let SC = 0b1, opc = opc in defm S : BaseRCWOP<"rcw" # "s" # op >;13009}13010 13011//---13012// 128-bit atomic instructions (FEAT_LSE128)13013//---13014 13015let mayLoad = 1, mayStore = 1, hasSideEffects = 0 in13016class LSE128Base<bits<3> op0, bits<2> AR, bit o3, string asm>13017: I<(outs GPR64common:$Rt_wb, GPR64common:$Rt2_wb),13018 (ins GPR64common:$Rt, GPR64common:$Rt2, GPR64sp:$Rn),13019 asm, "\t$Rt, $Rt2, [$Rn]",13020 "$Rt = $Rt_wb, $Rt2 = $Rt2_wb", []>,13021 Sched<[]> {13022 bits<5> Rt;13023 bits<5> Rt2;13024 bits<5> Rn;13025 let Inst{31-24} = 0b00011001;13026 let Inst{23-22} = AR;13027 let Inst{21} = 0b1;13028 let Inst{20-16} = Rt2;13029 let Inst{15} = o3;13030 let Inst{14-12} = op0;13031 let Inst{11-10} = 0b00;13032 let Inst{9-5} = Rn;13033 let Inst{4-0} = Rt;13034}13035 13036//---13037// 128-bit System Instructions (FEAT_SYSINSTR128)13038//---13039 13040// Instruction encoding:13041//13042// 31 19|18 16|15 12|11 8|7 5|4 013043// SYSP 1101010101001| op1| Cn| Cm|op2| Rt13044 13045// Instruction syntax:13046//13047// SYSP #<op1>, <Cn>, <Cm>, #<op2>{, <Xt>, <Xt+1>}13048 13049class RtSystemI128<bit L, dag oops, dag iops, string asm, string operands, list<dag> pattern = []> :13050 RtSystemI<L, oops, iops, asm, operands, pattern> {13051 let Inst{22} = 0b1; // override BaseSystemI13052}13053 13054class BaseSYSPEncoding<bit L, string asm, string operands, dag outputs, dag inputs>13055 : RtSystemI128<L, outputs, inputs, asm, operands> {13056 bits<3> op1;13057 bits<4> Cn;13058 bits<4> Cm;13059 bits<3> op2;13060 let Inst{20-19} = 0b01;13061 let Inst{18-16} = op1;13062 let Inst{15-12} = Cn;13063 let Inst{11-8} = Cm;13064 let Inst{7-5} = op2;13065}13066class SystemPXtI<bit L, string asm> :13067 BaseSYSPEncoding<L, asm, "\t$op1, $Cn, $Cm, $op2, $Rt", (outs),13068 (ins imm0_7:$op1, sys_cr_op:$Cn, sys_cr_op:$Cm, imm0_7:$op2, XSeqPairClassOperand:$Rt)>;13069 13070//----------------------------------------------------------------------------13071// 2023 Armv9.5 Extensions13072//----------------------------------------------------------------------------13073 13074//---13075// Checked Pointer Arithmetic (FEAT_CPA)13076//---13077 13078def LSLImm3ShiftOperand : AsmOperandClass {13079 let SuperClasses = [ExtendOperandLSL64];13080 let Name = "LSLImm3Shift";13081 let RenderMethod = "addLSLImm3ShifterOperands";13082 let DiagnosticType = "AddSubLSLImm3ShiftLarge";13083}13084 13085def lsl_imm3_shift_operand : Operand<i64> {13086 let PrintMethod = "printShifter";13087 let ParserMatchClass = LSLImm3ShiftOperand;13088}13089 13090// Base CPA scalar add/subtract with lsl #imm3 shift13091class BaseAddSubCPA<bit isSub, string asm> : I<(outs GPR64sp:$Rd),13092 (ins GPR64sp:$Rn, GPR64:$Rm, lsl_imm3_shift_operand:$shift_imm),13093 asm, "\t$Rd, $Rn, $Rm$shift_imm", "", []>, Sched<[]> {13094 bits<5> Rd;13095 bits<5> Rn;13096 bits<5> Rm;13097 bits<3> shift_imm;13098 let Inst{31} = 0b1;13099 let Inst{30} = isSub;13100 let Inst{29-21} = 0b011010000;13101 let Inst{20-16} = Rm;13102 let Inst{15-13} = 0b001;13103 let Inst{12-10} = shift_imm;13104 let Inst{9-5} = Rn;13105 let Inst{4-0} = Rd;13106}13107 13108// Alias for CPA scalar add/subtract with no shift13109class AddSubCPAAlias<string asm, Instruction inst>13110 : InstAlias<asm#"\t$Rd, $Rn, $Rm",13111 (inst GPR64sp:$Rd, GPR64sp:$Rn, GPR64:$Rm, 0)>;13112 13113multiclass AddSubCPA<bit isSub, string asm> {13114 def _shift : BaseAddSubCPA<isSub, asm>;13115 def _noshift : AddSubCPAAlias<asm, !cast<Instruction>(NAME#"_shift")>;13116}13117 13118class MulAccumCPA<bit isSub, string asm>13119 : BaseMulAccum<isSub, 0b011, GPR64, GPR64, asm, []>, Sched<[]> {13120 let Inst{31} = 0b1;13121}13122 13123 13124//----------------------------------------------------------------------------13125// 2024 Armv9.6 Extensions13126//----------------------------------------------------------------------------13127 13128//---13129// Compare-and-branch instructions.13130//---13131 13132class BaseCmpBranchRegister<RegisterClass regtype, bit sf, bits<3> cc,13133 bits<2>sz, string asm>13134 : I<(outs), (ins regtype:$Rt, regtype:$Rm, am_brcmpcond:$target),13135 asm, "\t$Rt, $Rm, $target", "",13136 []>,13137 Sched<[WriteBr]> {13138 let isBranch = 1;13139 let isTerminator = 1;13140 13141 bits<5> Rm;13142 bits<5> Rt;13143 bits<9> target;13144 let Inst{31} = sf;13145 let Inst{30-24} = 0b1110100;13146 let Inst{23-21} = cc;13147 let Inst{20-16} = Rm;13148 let Inst{15-14} = sz;13149 let Inst{13-5} = target;13150 let Inst{4-0} = Rt;13151}13152 13153multiclass CmpBranchRegister<bits<3> cc, string asm> {13154 def Wrr : BaseCmpBranchRegister<GPR32, 0b0, cc, 0b00, asm>;13155 def Xrr : BaseCmpBranchRegister<GPR64, 0b1, cc, 0b00, asm>;13156}13157 13158class BaseCmpBranchImmediate<RegisterClass regtype, bit sf, bits<3> cc,13159 Operand imm_ty, string asm>13160 : I<(outs), (ins regtype:$Rt, imm_ty:$imm, am_brcmpcond:$target),13161 asm, "\t$Rt, $imm, $target", "",13162 []>,13163 Sched<[WriteBr]> {13164 let isBranch = 1;13165 let isTerminator = 1;13166 13167 bits<5> Rt;13168 bits<6> imm;13169 bits<9> target;13170 let Inst{31} = sf;13171 let Inst{30-24} = 0b1110101;13172 let Inst{23-21} = cc;13173 let Inst{20-15} = imm;13174 let Inst{14} = 0b0;13175 let Inst{13-5} = target;13176 let Inst{4-0} = Rt;13177}13178 13179multiclass CmpBranchImmediate<bits<3> cc, string imm_ty, string asm> {13180 def Wri : BaseCmpBranchImmediate<GPR32, 0b0, cc, !cast<Operand>(imm_ty # "_32b"), asm>;13181 def Xri : BaseCmpBranchImmediate<GPR64, 0b1, cc, !cast<Operand>(imm_ty # "_64b"), asm>;13182}13183 13184multiclass CmpBranchImmediateAlias<string mnemonic, string insn, string imm_ty> {13185 def : InstAlias<mnemonic # "\t$Rt, $imm, $target",13186 (!cast<Instruction>(insn # "Wri") GPR32:$Rt,13187 !cast<Operand>(imm_ty # "_32b"):$imm,13188 am_brcmpcond:$target), 0>;13189 def : InstAlias<mnemonic # "\t$Rt, $imm, $target",13190 (!cast<Instruction>(insn # "Xri") GPR64:$Rt,13191 !cast<Operand>(imm_ty # "_64b"):$imm,13192 am_brcmpcond:$target), 0>;13193}13194 13195multiclass CmpBranchWRegisterAlias<string mnemonic, string insn> {13196 def : InstAlias<mnemonic # "\t$Rt, $Rm, $target",13197 (!cast<Instruction>(insn # "Wrr") GPR32:$Rm, GPR32:$Rt, am_brcmpcond:$target), 0>;13198}13199 13200multiclass CmpBranchRegisterAlias<string mnemonic, string insn> {13201 defm : CmpBranchWRegisterAlias<mnemonic, insn>;13202 13203 def : InstAlias<mnemonic # "\t$Rt, $Rm, $target",13204 (!cast<Instruction>(insn # "Xrr") GPR64:$Rm, GPR64:$Rt, am_brcmpcond:$target), 0>;13205}13206 13207class CmpBranchRegisterPseudo<RegisterClass regtype>13208 : Pseudo<(outs),13209 (ins ccode:$Cond, regtype:$Rt, regtype:$Rm, am_brcmpcond:$Target),13210 []>,13211 Sched<[WriteBr]> {13212 let isBranch = 1;13213 let isTerminator = 1;13214}13215 13216// Cmpbr pseudo instruction, encoding potentially folded zero-, sign-extension,13217// assertzext and/or assersext.13218class CmpBranchExtRegisterPseudo13219 : Pseudo<(outs),13220 (ins ccode:$Cond, GPR32:$Rt, GPR32:$Rm, am_brcmpcond:$Target,13221 simm8_32b:$ExtRt, simm8_32b:$ExtRm),13222 []>,13223 Sched<[WriteBr]> {13224 let isBranch = 1;13225 let isTerminator = 1;13226}13227 13228class CmpBranchImmediatePseudo<RegisterClass regtype, ImmLeaf imtype>13229 : Pseudo<(outs), (ins ccode:$Cond, regtype:$Rt, imtype:$Imm, am_brcmpcond:$Target), []>,13230 Sched<[WriteBr]> {13231 let isBranch = 1;13232 let isTerminator = 1;13233}13234 13235//----------------------------------------------------------------------------13236// Allow the size specifier tokens to be upper case, not just lower.13237def : TokenAlias<".4B", ".4b">; // Add dot product13238def : TokenAlias<".8B", ".8b">;13239def : TokenAlias<".4H", ".4h">;13240def : TokenAlias<".2S", ".2s">;13241def : TokenAlias<".1D", ".1d">;13242def : TokenAlias<".16B", ".16b">;13243def : TokenAlias<".8H", ".8h">;13244def : TokenAlias<".4S", ".4s">;13245def : TokenAlias<".2D", ".2d">;13246def : TokenAlias<".1Q", ".1q">;13247def : TokenAlias<".2H", ".2h">;13248def : TokenAlias<".2B", ".2b">;13249def : TokenAlias<".B", ".b">;13250def : TokenAlias<".H", ".h">;13251def : TokenAlias<".S", ".s">;13252def : TokenAlias<".D", ".d">;13253def : TokenAlias<".Q", ".q">;13254 13255//----------------------------------------------------------------------------13256// 2024 Armv9.6 Extensions13257//----------------------------------------------------------------------------13258 13259let mayLoad = 1, mayStore = 1 in13260class BaseAtomicFPLoad<RegisterClass regtype, bits<2> sz, bits<2> AR,13261 bits<3> op0, string asm>13262: I<(outs regtype:$Rt),13263 (ins regtype:$Rs, GPR64sp:$Rn),13264 asm, "\t$Rs, $Rt, [$Rn]","", []>,13265 Sched<[]> {13266 bits<5> Rt;13267 bits<5> Rs;13268 bits<5> Rn;13269 let Inst{31-30} = sz;13270 let Inst{29-24} = 0b111100;13271 let Inst{23-22} = AR;13272 let Inst{21} = 0b1;13273 let Inst{20-16} = Rs;13274 let Inst{15} = 0b0;13275 let Inst{14-12} = op0;13276 let Inst{11-10} = 0b00;13277 let Inst{9-5} = Rn;13278 let Inst{4-0} = Rt;13279}13280 13281multiclass AtomicFPLoad<bits<2> AR, bits<3> op0, string asm> {13282 def D : BaseAtomicFPLoad<FPR64, 0b11, AR, op0, asm>;13283 def S : BaseAtomicFPLoad<FPR32, 0b10, AR, op0, asm>;13284 def H : BaseAtomicFPLoad<FPR16, 0b01, AR, op0, asm>;13285}13286 13287let mayLoad = 1, mayStore = 1 in13288class BaseAtomicFPStore<RegisterClass regtype, bits<2> sz, bit R,13289 bits<3> op0, string asm>13290: I<(outs),13291 (ins regtype:$Rs, GPR64sp:$Rn),13292 asm, "\t$Rs, [$Rn]",13293 "", []>,13294 Sched<[]> {13295 bits<5> Rt;13296 bits<5> Rs;13297 bits<5> Rn;13298 let Inst{31-30} = sz;13299 let Inst{29-23} = 0b1111000;13300 let Inst{22} = R;13301 let Inst{21} = 0b1;13302 let Inst{20-16} = Rs;13303 let Inst{15} = 0b1;13304 let Inst{14-12} = op0;13305 let Inst{11-10} = 0b00;13306 let Inst{9-5} = Rn;13307 let Inst{4-0} = 0b11111;13308}13309 13310multiclass AtomicFPStore<bit R, bits<3> op0, string asm> {13311 def D : BaseAtomicFPStore<FPR64, 0b11, R, op0, asm>;13312 def S : BaseAtomicFPStore<FPR32, 0b10, R, op0, asm>;13313 def H : BaseAtomicFPStore<FPR16, 0b01, R, op0, asm>;13314}13315 13316class BaseSIMDThreeSameVectorFP8MatrixMul<string asm, bits<2> size, string kind, list<dag> pattern>13317 : BaseSIMDThreeSameVectorTied<1, 1, {size, 0}, 0b11101,13318 V128, asm, ".16b", pattern> {13319 let AsmString = !strconcat(asm, "{\t$Rd", kind, ", $Rn.16b, $Rm.16b",13320 "|", kind, "\t$Rd, $Rn, $Rm}");13321}13322 13323multiclass SIMDThreeSameVectorFP8MatrixMul<string asm, SDPatternOperator OpNode>{13324 def v8f16: BaseSIMDThreeSameVectorFP8MatrixMul<asm, 0b00, ".8h",13325 [(set (v8f16 V128:$dst), (OpNode (v8f16 V128:$Rd),13326 (v16i8 V128:$Rn),13327 (v16i8 V128:$Rm)))]> {13328 let Predicates = [HasNEON, HasF8F16MM];13329 }13330 def v4f32: BaseSIMDThreeSameVectorFP8MatrixMul<asm, 0b10, ".4s",13331 [(set (v4f32 V128:$dst), (OpNode (v4f32 V128:$Rd),13332 (v16i8 V128:$Rn),13333 (v16i8 V128:$Rm)))]> {13334 let Predicates = [HasNEON, HasF8F32MM];13335 }13336}13337 13338//----------------------------------------------------------------------------13339// Contention Management Hints - FEAT_CMH13340//----------------------------------------------------------------------------13341 13342class SHUHInst<string asm> : I<13343 (outs),13344 (ins CMHPriorityHint_op:$priority),13345 asm, "\t$priority", "", []>, Sched<[]> {13346 bits<1> priority;13347 let Inst{31-12} = 0b11010101000000110010;13348 let Inst{11-8} = 0b0110;13349 let Inst{7-6} = 0b01;13350 let Inst{5} = priority;13351 let Inst{4-0} = 0b11111;13352}13353 13354multiclass SHUH<string asm> {13355 def NAME : SHUHInst<asm>;13356 def : InstAlias<asm, (!cast<Instruction>(NAME) 0), 1>;13357}13358 13359class STCPHInst<string asm> : I<13360 (outs),13361 (ins),13362 asm, "", "", []>, Sched<[]> {13363 let Inst{31-12} = 0b11010101000000110010;13364 let Inst{11-8} = 0b0110;13365 let Inst{7-5} = 0b100;13366 let Inst{4-0} = 0b11111;13367}13368 13369//---13370// Permission Overlays Extension 2 (FEAT_S1POE2)13371//---13372 13373class TCHANGERegInst<string asm, bit isB> : I<13374 (outs GPR64:$Xd),13375 (ins GPR64:$Xn, TIndexhint_op:$nb),13376 asm, "\t$Xd, $Xn, $nb", "", []>, Sched<[]> {13377 bits<5> Xd;13378 bits<5> Xn;13379 bits<1> nb;13380 let Inst{31-19} = 0b1101010110000;13381 let Inst{18} = isB;13382 let Inst{17} = nb;13383 let Inst{16-10} = 0b0000000;13384 let Inst{9-5} = Xn;13385 let Inst{4-0} = Xd;13386}13387 13388class TCHANGEImmInst<string asm, bit isB> : I<13389 (outs GPR64:$Xd),13390 (ins imm0_127:$imm, TIndexhint_op:$nb),13391 asm, "\t$Xd, $imm, $nb", "", []>, Sched<[]> {13392 bits<5> Xd;13393 bits<7> imm;13394 bits<1> nb;13395 let Inst{31-19} = 0b1101010110010;13396 let Inst{18} = isB;13397 let Inst{17} = nb;13398 let Inst{16-12} = 0b00000;13399 let Inst{11-5} = imm;13400 let Inst{4-0} = Xd;13401}13402 13403class TENTERInst<string asm> : I<13404 (outs),13405 (ins imm0_127:$imm, TIndexhint_op:$nb),13406 asm, "\t$imm, $nb", "", []>, Sched<[]> {13407 bits<7> imm;13408 bits<1> nb;13409 let Inst{31-18} = 0b11010100111000;13410 let Inst{17} = nb;13411 let Inst{16-12} = 0b00000;13412 let Inst{11-5} = imm;13413 let Inst{4-0} = 0b00000;13414}13415 13416class TEXITInst<string asm> : I<13417 (outs),13418 (ins TIndexhint_op:$nb),13419 asm, "\t$nb", "", []>, Sched<[]> {13420 bits<1> nb;13421 let Inst{31-11} = 0b110101101111111100000;13422 let Inst{10} = nb;13423 let Inst{9-0} = 0b1111100000;13424}13425 13426 13427multiclass TCHANGEReg<string asm , bit isB> {13428 def NAME : TCHANGERegInst<asm, isB>;13429 def : InstAlias<asm # "\t$Xd, $Xn",13430 (!cast<Instruction>(NAME) GPR64:$Xd, GPR64:$Xn, 0), 1>;13431}13432 13433multiclass TCHANGEImm<string asm, bit isB> {13434 def NAME : TCHANGEImmInst<asm, isB>;13435 def : InstAlias<asm # "\t$Xd, $imm",13436 (!cast<Instruction>(NAME) GPR64:$Xd, imm0_127:$imm, 0), 1>;13437}13438 13439multiclass TENTER<string asm> {13440 def NAME : TENTERInst<asm>;13441 def : InstAlias<asm # "\t$imm",13442 (!cast<Instruction>(NAME) imm0_127:$imm, 0), 1>;13443}13444 13445multiclass TEXIT<string asm> {13446 def NAME : TEXITInst<asm>;13447 def : InstAlias<asm, (!cast<Instruction>(NAME) 0), 1>;13448}13449