1//===-- SystemZOperators.td - SystemZ-specific operators ------*- tblgen-*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9 10//===----------------------------------------------------------------------===// 11// Type profiles 12//===----------------------------------------------------------------------===// 13def SDT_CallSeqStart : SDCallSeqStart<[SDTCisVT<0, i64>]>; 14def SDT_CallSeqEnd : SDCallSeqEnd<[SDTCisVT<0, i64>, 15 SDTCisVT<1, i64>]>; 16def SDT_ZCall : SDTypeProfile<0, -1, [SDTCisPtrTy<0>]>; 17def SDT_ZCmp : SDTypeProfile<0, 2, [SDTCisSameAs<0, 1>]>; 18def SDT_ZICmp : SDTypeProfile<0, 3, 19 [SDTCisSameAs<0, 1>, 20 SDTCisVT<2, i32>]>; 21def SDT_ZBRCCMask : SDTypeProfile<0, 3, 22 [SDTCisVT<0, i32>, 23 SDTCisVT<1, i32>, 24 SDTCisVT<2, OtherVT>]>; 25def SDT_ZSelectCCMask : SDTypeProfile<1, 4, 26 [SDTCisSameAs<0, 1>, 27 SDTCisSameAs<1, 2>, 28 SDTCisVT<3, i32>, 29 SDTCisVT<4, i32>]>; 30def SDT_ZWrapPtr : SDTypeProfile<1, 1, 31 [SDTCisSameAs<0, 1>, 32 SDTCisPtrTy<0>]>; 33def SDT_ZWrapOffset : SDTypeProfile<1, 2, 34 [SDTCisSameAs<0, 1>, 35 SDTCisSameAs<0, 2>, 36 SDTCisPtrTy<0>]>; 37def SDT_ZAdjDynAlloc : SDTypeProfile<1, 0, [SDTCisVT<0, i64>]>; 38def SDT_ZExtractAccess : SDTypeProfile<1, 1, 39 [SDTCisVT<0, i32>, 40 SDTCisVT<1, i32>]>; 41def SDT_ZGR128Binary32 : SDTypeProfile<1, 2, 42 [SDTCisVT<0, untyped>, 43 SDTCisVT<1, untyped>, 44 SDTCisVT<2, i32>]>; 45def SDT_ZGR128Binary64 : SDTypeProfile<1, 2, 46 [SDTCisVT<0, untyped>, 47 SDTCisVT<1, untyped>, 48 SDTCisVT<2, i64>]>; 49def SDT_ZAtomicLoadBinaryW : SDTypeProfile<1, 5, 50 [SDTCisVT<0, i32>, 51 SDTCisPtrTy<1>, 52 SDTCisVT<2, i32>, 53 SDTCisVT<3, i32>, 54 SDTCisVT<4, i32>, 55 SDTCisVT<5, i32>]>; 56def SDT_ZAtomicCmpSwapW : SDTypeProfile<1, 6, 57 [SDTCisVT<0, i32>, 58 SDTCisPtrTy<1>, 59 SDTCisVT<2, i32>, 60 SDTCisVT<3, i32>, 61 SDTCisVT<4, i32>, 62 SDTCisVT<5, i32>, 63 SDTCisVT<6, i32>]>; 64def SDT_ZMemMemLength : SDTypeProfile<0, 3, 65 [SDTCisPtrTy<0>, 66 SDTCisPtrTy<1>, 67 SDTCisVT<2, i64>]>; 68def SDT_ZMemMemLoop : SDTypeProfile<0, 4, 69 [SDTCisPtrTy<0>, 70 SDTCisPtrTy<1>, 71 SDTCisVT<2, i64>, 72 SDTCisVT<3, i64>]>; 73def SDT_ZString : SDTypeProfile<1, 3, 74 [SDTCisPtrTy<0>, 75 SDTCisPtrTy<1>, 76 SDTCisPtrTy<2>, 77 SDTCisVT<3, i32>]>; 78def SDT_ZI32Intrinsic : SDTypeProfile<1, 0, [SDTCisVT<0, i32>]>; 79def SDT_ZPrefetch : SDTypeProfile<0, 2, 80 [SDTCisVT<0, i32>, 81 SDTCisPtrTy<1>]>; 82def SDT_ZTBegin : SDTypeProfile<0, 2, 83 [SDTCisPtrTy<0>, 84 SDTCisVT<1, i32>]>; 85 86//===----------------------------------------------------------------------===// 87// Node definitions 88//===----------------------------------------------------------------------===// 89 90// These are target-independent nodes, but have target-specific formats. 91def callseq_start : SDNode<"ISD::CALLSEQ_START", SDT_CallSeqStart, 92 [SDNPHasChain, SDNPSideEffect, SDNPOutGlue]>; 93def callseq_end : SDNode<"ISD::CALLSEQ_END", SDT_CallSeqEnd, 94 [SDNPHasChain, SDNPSideEffect, SDNPOptInGlue, 95 SDNPOutGlue]>; 96def global_offset_table : SDNode<"ISD::GLOBAL_OFFSET_TABLE", SDTPtrLeaf>; 97 98// Nodes for SystemZISD::*. See SystemZISelLowering.h for more details. 99def z_retflag : SDNode<"SystemZISD::RET_FLAG", SDTNone, 100 [SDNPHasChain, SDNPOptInGlue, SDNPVariadic]>; 101def z_call : SDNode<"SystemZISD::CALL", SDT_ZCall, 102 [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue, 103 SDNPVariadic]>; 104def z_sibcall : SDNode<"SystemZISD::SIBCALL", SDT_ZCall, 105 [SDNPHasChain, SDNPOutGlue, SDNPOptInGlue, 106 SDNPVariadic]>; 107def z_tls_gdcall : SDNode<"SystemZISD::TLS_GDCALL", SDT_ZCall, 108 [SDNPHasChain, SDNPInGlue, SDNPOutGlue, 109 SDNPVariadic]>; 110def z_tls_ldcall : SDNode<"SystemZISD::TLS_LDCALL", SDT_ZCall, 111 [SDNPHasChain, SDNPInGlue, SDNPOutGlue, 112 SDNPVariadic]>; 113def z_pcrel_wrapper : SDNode<"SystemZISD::PCREL_WRAPPER", SDT_ZWrapPtr, []>; 114def z_pcrel_offset : SDNode<"SystemZISD::PCREL_OFFSET", 115 SDT_ZWrapOffset, []>; 116def z_iabs : SDNode<"SystemZISD::IABS", SDTIntUnaryOp, []>; 117def z_icmp : SDNode<"SystemZISD::ICMP", SDT_ZICmp, [SDNPOutGlue]>; 118def z_fcmp : SDNode<"SystemZISD::FCMP", SDT_ZCmp, [SDNPOutGlue]>; 119def z_tm : SDNode<"SystemZISD::TM", SDT_ZICmp, [SDNPOutGlue]>; 120def z_br_ccmask : SDNode<"SystemZISD::BR_CCMASK", SDT_ZBRCCMask, 121 [SDNPHasChain, SDNPInGlue]>; 122def z_select_ccmask : SDNode<"SystemZISD::SELECT_CCMASK", SDT_ZSelectCCMask, 123 [SDNPInGlue]>; 124def z_adjdynalloc : SDNode<"SystemZISD::ADJDYNALLOC", SDT_ZAdjDynAlloc>; 125def z_extract_access : SDNode<"SystemZISD::EXTRACT_ACCESS", 126 SDT_ZExtractAccess>; 127def z_popcnt : SDNode<"SystemZISD::POPCNT", SDTIntUnaryOp>; 128def z_umul_lohi64 : SDNode<"SystemZISD::UMUL_LOHI64", SDT_ZGR128Binary64>; 129def z_sdivrem32 : SDNode<"SystemZISD::SDIVREM32", SDT_ZGR128Binary32>; 130def z_sdivrem64 : SDNode<"SystemZISD::SDIVREM64", SDT_ZGR128Binary64>; 131def z_udivrem32 : SDNode<"SystemZISD::UDIVREM32", SDT_ZGR128Binary32>; 132def z_udivrem64 : SDNode<"SystemZISD::UDIVREM64", SDT_ZGR128Binary64>; 133 134def z_serialize : SDNode<"SystemZISD::SERIALIZE", SDTNone, 135 [SDNPHasChain, SDNPMayStore]>; 136 137class AtomicWOp<string name, SDTypeProfile profile = SDT_ZAtomicLoadBinaryW> 138 : SDNode<"SystemZISD::"##name, profile, 139 [SDNPHasChain, SDNPMayStore, SDNPMayLoad, SDNPMemOperand]>; 140 141def z_atomic_swapw : AtomicWOp<"ATOMIC_SWAPW">; 142def z_atomic_loadw_add : AtomicWOp<"ATOMIC_LOADW_ADD">; 143def z_atomic_loadw_sub : AtomicWOp<"ATOMIC_LOADW_SUB">; 144def z_atomic_loadw_and : AtomicWOp<"ATOMIC_LOADW_AND">; 145def z_atomic_loadw_or : AtomicWOp<"ATOMIC_LOADW_OR">; 146def z_atomic_loadw_xor : AtomicWOp<"ATOMIC_LOADW_XOR">; 147def z_atomic_loadw_nand : AtomicWOp<"ATOMIC_LOADW_NAND">; 148def z_atomic_loadw_min : AtomicWOp<"ATOMIC_LOADW_MIN">; 149def z_atomic_loadw_max : AtomicWOp<"ATOMIC_LOADW_MAX">; 150def z_atomic_loadw_umin : AtomicWOp<"ATOMIC_LOADW_UMIN">; 151def z_atomic_loadw_umax : AtomicWOp<"ATOMIC_LOADW_UMAX">; 152def z_atomic_cmp_swapw : AtomicWOp<"ATOMIC_CMP_SWAPW", SDT_ZAtomicCmpSwapW>; 153 154def z_mvc : SDNode<"SystemZISD::MVC", SDT_ZMemMemLength, 155 [SDNPHasChain, SDNPMayStore, SDNPMayLoad]>; 156def z_mvc_loop : SDNode<"SystemZISD::MVC_LOOP", SDT_ZMemMemLoop, 157 [SDNPHasChain, SDNPMayStore, SDNPMayLoad]>; 158def z_nc : SDNode<"SystemZISD::NC", SDT_ZMemMemLength, 159 [SDNPHasChain, SDNPMayStore, SDNPMayLoad]>; 160def z_nc_loop : SDNode<"SystemZISD::NC_LOOP", SDT_ZMemMemLoop, 161 [SDNPHasChain, SDNPMayStore, SDNPMayLoad]>; 162def z_oc : SDNode<"SystemZISD::OC", SDT_ZMemMemLength, 163 [SDNPHasChain, SDNPMayStore, SDNPMayLoad]>; 164def z_oc_loop : SDNode<"SystemZISD::OC_LOOP", SDT_ZMemMemLoop, 165 [SDNPHasChain, SDNPMayStore, SDNPMayLoad]>; 166def z_xc : SDNode<"SystemZISD::XC", SDT_ZMemMemLength, 167 [SDNPHasChain, SDNPMayStore, SDNPMayLoad]>; 168def z_xc_loop : SDNode<"SystemZISD::XC_LOOP", SDT_ZMemMemLoop, 169 [SDNPHasChain, SDNPMayStore, SDNPMayLoad]>; 170def z_clc : SDNode<"SystemZISD::CLC", SDT_ZMemMemLength, 171 [SDNPHasChain, SDNPOutGlue, SDNPMayLoad]>; 172def z_clc_loop : SDNode<"SystemZISD::CLC_LOOP", SDT_ZMemMemLoop, 173 [SDNPHasChain, SDNPOutGlue, SDNPMayLoad]>; 174def z_strcmp : SDNode<"SystemZISD::STRCMP", SDT_ZString, 175 [SDNPHasChain, SDNPOutGlue, SDNPMayLoad]>; 176def z_stpcpy : SDNode<"SystemZISD::STPCPY", SDT_ZString, 177 [SDNPHasChain, SDNPMayStore, SDNPMayLoad]>; 178def z_search_string : SDNode<"SystemZISD::SEARCH_STRING", SDT_ZString, 179 [SDNPHasChain, SDNPOutGlue, SDNPMayLoad]>; 180def z_ipm : SDNode<"SystemZISD::IPM", SDT_ZI32Intrinsic, 181 [SDNPInGlue]>; 182def z_prefetch : SDNode<"SystemZISD::PREFETCH", SDT_ZPrefetch, 183 [SDNPHasChain, SDNPMayLoad, SDNPMayStore, 184 SDNPMemOperand]>; 185 186def z_tbegin : SDNode<"SystemZISD::TBEGIN", SDT_ZTBegin, 187 [SDNPHasChain, SDNPOutGlue, SDNPMayStore, 188 SDNPSideEffect]>; 189def z_tbegin_nofloat : SDNode<"SystemZISD::TBEGIN_NOFLOAT", SDT_ZTBegin, 190 [SDNPHasChain, SDNPOutGlue, SDNPMayStore, 191 SDNPSideEffect]>; 192def z_tend : SDNode<"SystemZISD::TEND", SDTNone, 193 [SDNPHasChain, SDNPOutGlue, SDNPSideEffect]>; 194 195//===----------------------------------------------------------------------===// 196// Pattern fragments 197//===----------------------------------------------------------------------===// 198 199// Signed and unsigned comparisons. 200def z_scmp : PatFrag<(ops node:$a, node:$b), (z_icmp node:$a, node:$b, imm), [{ 201 unsigned Type = cast<ConstantSDNode>(N->getOperand(2))->getZExtValue(); 202 return Type != SystemZICMP::UnsignedOnly; 203}]>; 204def z_ucmp : PatFrag<(ops node:$a, node:$b), (z_icmp node:$a, node:$b, imm), [{ 205 unsigned Type = cast<ConstantSDNode>(N->getOperand(2))->getZExtValue(); 206 return Type != SystemZICMP::SignedOnly; 207}]>; 208 209// Register- and memory-based TEST UNDER MASK. 210def z_tm_reg : PatFrag<(ops node:$a, node:$b), (z_tm node:$a, node:$b, imm)>; 211def z_tm_mem : PatFrag<(ops node:$a, node:$b), (z_tm node:$a, node:$b, 0)>; 212 213// Register sign-extend operations. Sub-32-bit values are represented as i32s. 214def sext8 : PatFrag<(ops node:$src), (sext_inreg node:$src, i8)>; 215def sext16 : PatFrag<(ops node:$src), (sext_inreg node:$src, i16)>; 216def sext32 : PatFrag<(ops node:$src), (sext (i32 node:$src))>; 217 218// Register zero-extend operations. Sub-32-bit values are represented as i32s. 219def zext8 : PatFrag<(ops node:$src), (and node:$src, 0xff)>; 220def zext16 : PatFrag<(ops node:$src), (and node:$src, 0xffff)>; 221def zext32 : PatFrag<(ops node:$src), (zext (i32 node:$src))>; 222 223// Typed floating-point loads. 224def loadf32 : PatFrag<(ops node:$src), (f32 (load node:$src))>; 225def loadf64 : PatFrag<(ops node:$src), (f64 (load node:$src))>; 226 227// Extending loads in which the extension type can be signed. 228def asextload : PatFrag<(ops node:$ptr), (unindexedload node:$ptr), [{ 229 unsigned Type = cast<LoadSDNode>(N)->getExtensionType(); 230 return Type == ISD::EXTLOAD || Type == ISD::SEXTLOAD; 231}]>; 232def asextloadi8 : PatFrag<(ops node:$ptr), (asextload node:$ptr), [{ 233 return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i8; 234}]>; 235def asextloadi16 : PatFrag<(ops node:$ptr), (asextload node:$ptr), [{ 236 return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i16; 237}]>; 238def asextloadi32 : PatFrag<(ops node:$ptr), (asextload node:$ptr), [{ 239 return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i32; 240}]>; 241 242// Extending loads in which the extension type can be unsigned. 243def azextload : PatFrag<(ops node:$ptr), (unindexedload node:$ptr), [{ 244 unsigned Type = cast<LoadSDNode>(N)->getExtensionType(); 245 return Type == ISD::EXTLOAD || Type == ISD::ZEXTLOAD; 246}]>; 247def azextloadi8 : PatFrag<(ops node:$ptr), (azextload node:$ptr), [{ 248 return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i8; 249}]>; 250def azextloadi16 : PatFrag<(ops node:$ptr), (azextload node:$ptr), [{ 251 return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i16; 252}]>; 253def azextloadi32 : PatFrag<(ops node:$ptr), (azextload node:$ptr), [{ 254 return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i32; 255}]>; 256 257// Extending loads in which the extension type doesn't matter. 258def anyextload : PatFrag<(ops node:$ptr), (unindexedload node:$ptr), [{ 259 return cast<LoadSDNode>(N)->getExtensionType() != ISD::NON_EXTLOAD; 260}]>; 261def anyextloadi8 : PatFrag<(ops node:$ptr), (anyextload node:$ptr), [{ 262 return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i8; 263}]>; 264def anyextloadi16 : PatFrag<(ops node:$ptr), (anyextload node:$ptr), [{ 265 return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i16; 266}]>; 267def anyextloadi32 : PatFrag<(ops node:$ptr), (anyextload node:$ptr), [{ 268 return cast<LoadSDNode>(N)->getMemoryVT() == MVT::i32; 269}]>; 270 271// Aligned loads. 272class AlignedLoad<SDPatternOperator load> 273 : PatFrag<(ops node:$addr), (load node:$addr), [{ 274 auto *Load = cast<LoadSDNode>(N); 275 return Load->getAlignment() >= Load->getMemoryVT().getStoreSize(); 276}]>; 277def aligned_load : AlignedLoad<load>; 278def aligned_asextloadi16 : AlignedLoad<asextloadi16>; 279def aligned_asextloadi32 : AlignedLoad<asextloadi32>; 280def aligned_azextloadi16 : AlignedLoad<azextloadi16>; 281def aligned_azextloadi32 : AlignedLoad<azextloadi32>; 282 283// Aligned stores. 284class AlignedStore<SDPatternOperator store> 285 : PatFrag<(ops node:$src, node:$addr), (store node:$src, node:$addr), [{ 286 auto *Store = cast<StoreSDNode>(N); 287 return Store->getAlignment() >= Store->getMemoryVT().getStoreSize(); 288}]>; 289def aligned_store : AlignedStore<store>; 290def aligned_truncstorei16 : AlignedStore<truncstorei16>; 291def aligned_truncstorei32 : AlignedStore<truncstorei32>; 292 293// Non-volatile loads. Used for instructions that might access the storage 294// location multiple times. 295class NonvolatileLoad<SDPatternOperator load> 296 : PatFrag<(ops node:$addr), (load node:$addr), [{ 297 auto *Load = cast<LoadSDNode>(N); 298 return !Load->isVolatile(); 299}]>; 300def nonvolatile_load : NonvolatileLoad<load>; 301def nonvolatile_anyextloadi8 : NonvolatileLoad<anyextloadi8>; 302def nonvolatile_anyextloadi16 : NonvolatileLoad<anyextloadi16>; 303def nonvolatile_anyextloadi32 : NonvolatileLoad<anyextloadi32>; 304 305// Non-volatile stores. 306class NonvolatileStore<SDPatternOperator store> 307 : PatFrag<(ops node:$src, node:$addr), (store node:$src, node:$addr), [{ 308 auto *Store = cast<StoreSDNode>(N); 309 return !Store->isVolatile(); 310}]>; 311def nonvolatile_store : NonvolatileStore<store>; 312def nonvolatile_truncstorei8 : NonvolatileStore<truncstorei8>; 313def nonvolatile_truncstorei16 : NonvolatileStore<truncstorei16>; 314def nonvolatile_truncstorei32 : NonvolatileStore<truncstorei32>; 315 316// A store of a load that can be implemented using MVC. 317def mvc_store : PatFrag<(ops node:$value, node:$addr), 318 (unindexedstore node:$value, node:$addr), 319 [{ return storeLoadCanUseMVC(N); }]>; 320 321// Binary read-modify-write operations on memory in which the other 322// operand is also memory and for which block operations like NC can 323// be used. There are two patterns for each operator, depending on 324// which operand contains the "other" load. 325multiclass block_op<SDPatternOperator operator> { 326 def "1" : PatFrag<(ops node:$value, node:$addr), 327 (unindexedstore (operator node:$value, 328 (unindexedload node:$addr)), 329 node:$addr), 330 [{ return storeLoadCanUseBlockBinary(N, 0); }]>; 331 def "2" : PatFrag<(ops node:$value, node:$addr), 332 (unindexedstore (operator (unindexedload node:$addr), 333 node:$value), 334 node:$addr), 335 [{ return storeLoadCanUseBlockBinary(N, 1); }]>; 336} 337defm block_and : block_op<and>; 338defm block_or : block_op<or>; 339defm block_xor : block_op<xor>; 340 341// Insertions. 342def inserti8 : PatFrag<(ops node:$src1, node:$src2), 343 (or (and node:$src1, -256), node:$src2)>; 344def insertll : PatFrag<(ops node:$src1, node:$src2), 345 (or (and node:$src1, 0xffffffffffff0000), node:$src2)>; 346def insertlh : PatFrag<(ops node:$src1, node:$src2), 347 (or (and node:$src1, 0xffffffff0000ffff), node:$src2)>; 348def inserthl : PatFrag<(ops node:$src1, node:$src2), 349 (or (and node:$src1, 0xffff0000ffffffff), node:$src2)>; 350def inserthh : PatFrag<(ops node:$src1, node:$src2), 351 (or (and node:$src1, 0x0000ffffffffffff), node:$src2)>; 352def insertlf : PatFrag<(ops node:$src1, node:$src2), 353 (or (and node:$src1, 0xffffffff00000000), node:$src2)>; 354def inserthf : PatFrag<(ops node:$src1, node:$src2), 355 (or (and node:$src1, 0x00000000ffffffff), node:$src2)>; 356 357// ORs that can be treated as insertions. 358def or_as_inserti8 : PatFrag<(ops node:$src1, node:$src2), 359 (or node:$src1, node:$src2), [{ 360 unsigned BitWidth = N->getValueType(0).getScalarType().getSizeInBits(); 361 return CurDAG->MaskedValueIsZero(N->getOperand(0), 362 APInt::getLowBitsSet(BitWidth, 8)); 363}]>; 364 365// ORs that can be treated as reversed insertions. 366def or_as_revinserti8 : PatFrag<(ops node:$src1, node:$src2), 367 (or node:$src1, node:$src2), [{ 368 unsigned BitWidth = N->getValueType(0).getScalarType().getSizeInBits(); 369 return CurDAG->MaskedValueIsZero(N->getOperand(1), 370 APInt::getLowBitsSet(BitWidth, 8)); 371}]>; 372 373// Negative integer absolute. 374def z_inegabs : PatFrag<(ops node:$src), (ineg (z_iabs node:$src))>; 375 376// Integer absolute, matching the canonical form generated by DAGCombiner. 377def z_iabs32 : PatFrag<(ops node:$src), 378 (xor (add node:$src, (sra node:$src, (i32 31))), 379 (sra node:$src, (i32 31)))>; 380def z_iabs64 : PatFrag<(ops node:$src), 381 (xor (add node:$src, (sra node:$src, (i32 63))), 382 (sra node:$src, (i32 63)))>; 383def z_inegabs32 : PatFrag<(ops node:$src), (ineg (z_iabs32 node:$src))>; 384def z_inegabs64 : PatFrag<(ops node:$src), (ineg (z_iabs64 node:$src))>; 385 386// Fused multiply-add and multiply-subtract, but with the order of the 387// operands matching SystemZ's MA and MS instructions. 388def z_fma : PatFrag<(ops node:$src1, node:$src2, node:$src3), 389 (fma node:$src2, node:$src3, node:$src1)>; 390def z_fms : PatFrag<(ops node:$src1, node:$src2, node:$src3), 391 (fma node:$src2, node:$src3, (fneg node:$src1))>; 392 393// Floating-point negative absolute. 394def fnabs : PatFrag<(ops node:$ptr), (fneg (fabs node:$ptr))>; 395 396// Create a unary operator that loads from memory and then performs 397// the given operation on it. 398class loadu<SDPatternOperator operator, SDPatternOperator load = load> 399 : PatFrag<(ops node:$addr), (operator (load node:$addr))>; 400 401// Create a store operator that performs the given unary operation 402// on the value before storing it. 403class storeu<SDPatternOperator operator, SDPatternOperator store = store> 404 : PatFrag<(ops node:$value, node:$addr), 405 (store (operator node:$value), node:$addr)>; 406