github.com/bir3/gocompiler@v0.9.2202/src/cmd/compile/internal/ssa/_gen/PPC64latelower.rules (about)

     1  // Copyright 2022 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // This file contains rules used by the laterLower pass.
     6  
     7  // Simplify ISEL x $0 z into ISELZ
     8  (ISEL [a] x (MOVDconst [0]) z) => (ISELZ [a] x z)
     9  // Simplify ISEL $0 y z into ISELZ by inverting comparison and reversing arguments.
    10  (ISEL [a] (MOVDconst [0]) y z) => (ISELZ [a^0x4] y z)
    11  
    12  // SETBC, SETBCR is supported on ISA 3.1(Power10) and newer, use ISELZ for
    13  // older targets
    14  (SETBC [2] cmp) && buildcfg.GOPPC64 <= 9 => (ISELZ [2] (MOVDconst [1]) cmp)
    15  (SETBCR [2] cmp) && buildcfg.GOPPC64 <= 9 => (ISELZ [6] (MOVDconst [1]) cmp)
    16  (SETBC [0] cmp) && buildcfg.GOPPC64 <= 9 => (ISELZ [0] (MOVDconst [1]) cmp)
    17  (SETBCR [0] cmp) && buildcfg.GOPPC64 <= 9 => (ISELZ [4] (MOVDconst [1]) cmp)
    18  (SETBC [1] cmp) && buildcfg.GOPPC64 <= 9 => (ISELZ [1] (MOVDconst [1]) cmp)
    19  (SETBCR [1] cmp) && buildcfg.GOPPC64 <= 9 => (ISELZ [5] (MOVDconst [1]) cmp)
    20  
    21  // Avoid using ANDCCconst if the value for CR0 is not needed, since ANDCCconst
    22  // always sets it.
    23  (Select0 z:(ANDCCconst [m] x)) && z.Uses == 1 && isPPC64ValidShiftMask(m) => (RLDICL [encodePPC64RotateMask(0,m,64)] x)
    24  // The upper bits of the smaller than register values is undefined. Take advantage of that.
    25  (AND <t> x:(MOVDconst [m]) n) && t.Size() <= 2 => (Select0 (ANDCCconst [int64(int16(m))] n))
    26  
    27  // Convert simple bit masks to an equivalent rldic[lr] if possible.
    28  (AND x:(MOVDconst [m]) n) && isPPC64ValidShiftMask(m) => (RLDICL [encodePPC64RotateMask(0,m,64)] n)
    29  (AND x:(MOVDconst [m]) n) && m != 0 && isPPC64ValidShiftMask(^m) => (RLDICR [encodePPC64RotateMask(0,m,64)] n)
    30  
    31  // If the RLDICL does not rotate its value, a shifted value can be merged.
    32  (RLDICL [em] x:(SRDconst [s] a)) && (em&0xFF0000) == 0 => (RLDICL [mergePPC64RLDICLandSRDconst(em, s)] a)
    33  
    34  // Convert rotated 32 bit masks on 32 bit values into rlwinm. In general, this leaves the upper 32 bits in an undefined state.
    35  (AND <t> x:(MOVDconst [m]) n) && t.Size() == 4 && isPPC64WordRotateMask(m) => (RLWINM [encodePPC64RotateMask(0,m,32)] n)
    36  
    37  // When PCRel is supported, paddi can add a 34b signed constant in one instruction.
    38  (ADD (MOVDconst [m]) x) && supportsPPC64PCRel() && (m<<30)>>30 == m => (ADDconst [m] x)
    39  
    40  
    41  // Where possible and practical, generate CC opcodes. Due to the structure of the rules, there are limits to how
    42  // a Value can be rewritten which make it impossible to correctly rewrite sibling Value users. To workaround this
    43  // case, candidates for CC opcodes are converted in two steps:
    44  //   1. Convert all (x (Op ...) ...) into (x (Select0 (OpCC ...) ...). See convertPPC64OpToOpCC for more
    45  //      detail on how and why this is done there.
    46  //   2. Rewrite (CMPconst [0] (Select0 (OpCC ...))) into (Select1 (OpCC...))
    47  // Note: to minimize potentially expensive regeneration of CC opcodes during the flagalloc pass, only rewrite if
    48  //       both ops are in the same block.
    49  (CMPconst [0] z:((ADD|AND|ANDN|OR|SUB|NOR|XOR) x y)) && v.Block == z.Block => (CMPconst [0] convertPPC64OpToOpCC(z))
    50  (CMPconst [0] z:((NEG|CNTLZD) x)) && v.Block == z.Block => (CMPconst [0] convertPPC64OpToOpCC(z))
    51  // Note: ADDCCconst only assembles to 1 instruction for int16 constants.
    52  (CMPconst [0] z:(ADDconst [c] x)) && int64(int16(c)) == c && v.Block == z.Block => (CMPconst [0] convertPPC64OpToOpCC(z))
    53  // And finally, fixup the flag user.
    54  (CMPconst <t> [0] (Select0 z:((ADD|AND|ANDN|OR|SUB|NOR|XOR)CC x y))) => (Select1 <t> z)
    55  (CMPconst <t> [0] (Select0 z:((ADDCCconst|NEGCC|CNTLZDCC) y))) => (Select1 <t> z)