]> Cypherpunks repositories - gostls13.git/commitdiff
cmd/compile: PPC64.rules for load/store address folding
authorLynn Boger <laboger@linux.vnet.ibm.com>
Thu, 18 Aug 2016 18:49:10 +0000 (13:49 -0500)
committerDavid Chase <drchase@google.com>
Mon, 22 Aug 2016 20:04:03 +0000 (20:04 +0000)
This adds some additional rules to improve loads and
stores for ppc64x.

Change-Id: I96b99c3a0019e6ac5393910c086f58330a04fc5a
Reviewed-on: https://go-review.googlesource.com/27354
Run-TryBot: David Chase <drchase@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: David Chase <drchase@google.com>
src/cmd/compile/internal/ssa/gen/PPC64.rules
src/cmd/compile/internal/ssa/gen/PPC64Ops.go
src/cmd/compile/internal/ssa/opGen.go
src/cmd/compile/internal/ssa/rewritePPC64.go

index 4e95e7251b49a44fb0ce4e27365be99d3c5ca26c..3f379129bd558c71945a2999235f090aadd0c8cc 100644 (file)
 (MOVHstore [off1] {sym} (ADDconst [off2] x) val mem) && is16Bit(off1+off2) -> (MOVHstore [off1+off2] {sym} x val mem)
 (MOVBstore [off1] {sym} (ADDconst [off2] x) val mem) && is16Bit(off1+off2) -> (MOVBstore [off1+off2] {sym} x val mem)
 
+(FMOVSstore [off1] {sym} (ADDconst [off2] ptr) val mem) && is16Bit(off1+off2) -> (FMOVSstore [off1+off2] {sym} ptr val mem)
+(FMOVDstore [off1] {sym} (ADDconst [off2] ptr) val mem) && is16Bit(off1+off2) -> (FMOVDstore [off1+off2] {sym} ptr val mem)
+
+(MOVBstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) ->
+        (MOVBstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
+(MOVHstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) ->
+        (MOVHstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
+(MOVWstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) ->
+        (MOVWstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
+(MOVDstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) ->
+        (MOVDstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
+
+(FMOVSstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) ->
+        (FMOVSstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
+(FMOVDstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem) && canMergeSym(sym1,sym2) ->
+        (FMOVDstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
+
+(MOVBload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) ->
+        (MOVBload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
+(MOVBZload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) ->
+        (MOVBZload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
+(MOVHload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) ->
+        (MOVHload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
+(MOVHZload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) ->
+        (MOVHZload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
+(MOVWload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) ->
+        (MOVWload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
+(MOVWZload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) ->
+        (MOVWZload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
+(MOVDload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) ->
+        (MOVDload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
+(FMOVSload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) ->
+        (FMOVSload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
+(FMOVDload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem) && canMergeSym(sym1,sym2) ->
+        (FMOVDload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
+
+// Fold offsets for loads.
+(FMOVSload [off1] {sym} (ADDconst [off2] ptr) mem) && is16Bit(off1+off2) -> (FMOVSload [off1+off2] {sym} ptr mem)
+(FMOVDload [off1] {sym} (ADDconst [off2] ptr) mem) && is16Bit(off1+off2) -> (FMOVDload [off1+off2] {sym} ptr mem)
+
+(MOVDload [off1] {sym} (ADDconst [off2] x) mem) && is16Bit(off1+off2) -> (MOVDload [off1+off2] {sym} x mem)
+(MOVWload [off1] {sym} (ADDconst [off2] x) mem) && is16Bit(off1+off2) -> (MOVWload [off1+off2] {sym} x mem)
+(MOVWZload [off1] {sym} (ADDconst [off2] x) mem) && is16Bit(off1+off2) -> (MOVWZload [off1+off2] {sym} x mem)
+(MOVHload [off1] {sym} (ADDconst [off2] x) mem) && is16Bit(off1+off2) -> (MOVHload [off1+off2] {sym} x mem)
+(MOVHZload [off1] {sym} (ADDconst [off2] x) mem) && is16Bit(off1+off2) -> (MOVHZload [off1+off2] {sym} x mem)
+(MOVBload [off1] {sym} (ADDconst [off2] x) mem) && is16Bit(off1+off2) -> (MOVBload [off1+off2] {sym} x mem)
+(MOVBZload [off1] {sym} (ADDconst [off2] x) mem) && is16Bit(off1+off2) -> (MOVBZload [off1+off2] {sym} x mem)
+
 // Store of zero -> storezero
 (MOVDstore [off] {sym} ptr (MOVDconst [c]) mem) && c == 0 -> (MOVDstorezero [off] {sym} ptr mem)
 (MOVWstore [off] {sym} ptr (MOVDconst [c]) mem) && c == 0 -> (MOVWstorezero [off] {sym} ptr mem)
index cbc13db5a7a1ae28fb77f60aa0725b0473b49e9c..09b6d316d0faa8de1e3e9489d183641d56d7081f 100644 (file)
@@ -241,8 +241,8 @@ func init() {
                {name: "MOVWZload", argLength: 2, reg: gpload, asm: "MOVWZ", aux: "SymOff", typ: "UInt32"}, // zero extend uint32 to uint64
                {name: "MOVDload", argLength: 2, reg: gpload, asm: "MOVD", aux: "SymOff", typ: "Int64"},
 
-               {name: "FMOVDload", argLength: 2, reg: fpload, asm: "FMOVD", typ: "Float64"},
-               {name: "FMOVSload", argLength: 2, reg: fpload, asm: "FMOVS", typ: "Float32"},
+               {name: "FMOVDload", argLength: 2, reg: fpload, asm: "FMOVD", aux: "SymOff", typ: "Float64"},
+               {name: "FMOVSload", argLength: 2, reg: fpload, asm: "FMOVS", aux: "SymOff", typ: "Float32"},
                {name: "MOVBstore", argLength: 3, reg: gpstore, asm: "MOVB", aux: "SymOff", typ: "Mem"},
                {name: "MOVHstore", argLength: 3, reg: gpstore, asm: "MOVH", aux: "SymOff", typ: "Mem"},
                {name: "MOVWstore", argLength: 3, reg: gpstore, asm: "MOVW", aux: "SymOff", typ: "Mem"},
index 14c0d761c5082c61876696384ca219f435f2798b..a5d41abb4f2939972ecb98c72c7f03f8c2bdf4fb 100644 (file)
@@ -14155,9 +14155,10 @@ var opcodeTable = [...]opInfo{
                },
        },
        {
-               name:   "FMOVDload",
-               argLen: 2,
-               asm:    ppc64.AFMOVD,
+               name:    "FMOVDload",
+               auxType: auxSymOff,
+               argLen:  2,
+               asm:     ppc64.AFMOVD,
                reg: regInfo{
                        inputs: []inputInfo{
                                {0, 536866815}, // SP SB R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29
@@ -14168,9 +14169,10 @@ var opcodeTable = [...]opInfo{
                },
        },
        {
-               name:   "FMOVSload",
-               argLen: 2,
-               asm:    ppc64.AFMOVS,
+               name:    "FMOVSload",
+               auxType: auxSymOff,
+               argLen:  2,
+               asm:     ppc64.AFMOVS,
                reg: regInfo{
                        inputs: []inputInfo{
                                {0, 536866815}, // SP SB R3 R4 R5 R6 R7 R8 R9 R10 R11 R12 R14 R15 R16 R17 R18 R19 R20 R21 R22 R23 R24 R25 R26 R27 R28 R29
index b6d474c00606c1cef52d83f06d78668790f36e12..4be68fda2bd2790676458a2fd80061818d6ad8d6 100644 (file)
@@ -350,6 +350,14 @@ func rewriteValuePPC64(v *Value, config *Config) bool {
                return rewriteValuePPC64_OpPPC64CMPconst(v, config)
        case OpPPC64Equal:
                return rewriteValuePPC64_OpPPC64Equal(v, config)
+       case OpPPC64FMOVDload:
+               return rewriteValuePPC64_OpPPC64FMOVDload(v, config)
+       case OpPPC64FMOVDstore:
+               return rewriteValuePPC64_OpPPC64FMOVDstore(v, config)
+       case OpPPC64FMOVSload:
+               return rewriteValuePPC64_OpPPC64FMOVSload(v, config)
+       case OpPPC64FMOVSstore:
+               return rewriteValuePPC64_OpPPC64FMOVSstore(v, config)
        case OpPPC64GreaterEqual:
                return rewriteValuePPC64_OpPPC64GreaterEqual(v, config)
        case OpPPC64GreaterThan:
@@ -358,18 +366,32 @@ func rewriteValuePPC64(v *Value, config *Config) bool {
                return rewriteValuePPC64_OpPPC64LessEqual(v, config)
        case OpPPC64LessThan:
                return rewriteValuePPC64_OpPPC64LessThan(v, config)
+       case OpPPC64MOVBZload:
+               return rewriteValuePPC64_OpPPC64MOVBZload(v, config)
+       case OpPPC64MOVBload:
+               return rewriteValuePPC64_OpPPC64MOVBload(v, config)
        case OpPPC64MOVBstore:
                return rewriteValuePPC64_OpPPC64MOVBstore(v, config)
        case OpPPC64MOVBstorezero:
                return rewriteValuePPC64_OpPPC64MOVBstorezero(v, config)
+       case OpPPC64MOVDload:
+               return rewriteValuePPC64_OpPPC64MOVDload(v, config)
        case OpPPC64MOVDstore:
                return rewriteValuePPC64_OpPPC64MOVDstore(v, config)
        case OpPPC64MOVDstorezero:
                return rewriteValuePPC64_OpPPC64MOVDstorezero(v, config)
+       case OpPPC64MOVHZload:
+               return rewriteValuePPC64_OpPPC64MOVHZload(v, config)
+       case OpPPC64MOVHload:
+               return rewriteValuePPC64_OpPPC64MOVHload(v, config)
        case OpPPC64MOVHstore:
                return rewriteValuePPC64_OpPPC64MOVHstore(v, config)
        case OpPPC64MOVHstorezero:
                return rewriteValuePPC64_OpPPC64MOVHstorezero(v, config)
+       case OpPPC64MOVWZload:
+               return rewriteValuePPC64_OpPPC64MOVWZload(v, config)
+       case OpPPC64MOVWload:
+               return rewriteValuePPC64_OpPPC64MOVWload(v, config)
        case OpPPC64MOVWstore:
                return rewriteValuePPC64_OpPPC64MOVWstore(v, config)
        case OpPPC64MOVWstorezero:
@@ -4170,6 +4192,222 @@ func rewriteValuePPC64_OpPPC64Equal(v *Value, config *Config) bool {
        }
        return false
 }
+func rewriteValuePPC64_OpPPC64FMOVDload(v *Value, config *Config) bool {
+       b := v.Block
+       _ = b
+       // match: (FMOVDload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
+       // cond: canMergeSym(sym1,sym2)
+       // result: (FMOVDload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
+       for {
+               off1 := v.AuxInt
+               sym1 := v.Aux
+               v_0 := v.Args[0]
+               if v_0.Op != OpPPC64MOVDaddr {
+                       break
+               }
+               off2 := v_0.AuxInt
+               sym2 := v_0.Aux
+               ptr := v_0.Args[0]
+               mem := v.Args[1]
+               if !(canMergeSym(sym1, sym2)) {
+                       break
+               }
+               v.reset(OpPPC64FMOVDload)
+               v.AuxInt = off1 + off2
+               v.Aux = mergeSym(sym1, sym2)
+               v.AddArg(ptr)
+               v.AddArg(mem)
+               return true
+       }
+       // match: (FMOVDload [off1] {sym} (ADDconst [off2] ptr) mem)
+       // cond: is16Bit(off1+off2)
+       // result: (FMOVDload [off1+off2] {sym} ptr mem)
+       for {
+               off1 := v.AuxInt
+               sym := v.Aux
+               v_0 := v.Args[0]
+               if v_0.Op != OpPPC64ADDconst {
+                       break
+               }
+               off2 := v_0.AuxInt
+               ptr := v_0.Args[0]
+               mem := v.Args[1]
+               if !(is16Bit(off1 + off2)) {
+                       break
+               }
+               v.reset(OpPPC64FMOVDload)
+               v.AuxInt = off1 + off2
+               v.Aux = sym
+               v.AddArg(ptr)
+               v.AddArg(mem)
+               return true
+       }
+       return false
+}
+func rewriteValuePPC64_OpPPC64FMOVDstore(v *Value, config *Config) bool {
+       b := v.Block
+       _ = b
+       // match: (FMOVDstore [off1] {sym} (ADDconst [off2] ptr) val mem)
+       // cond: is16Bit(off1+off2)
+       // result: (FMOVDstore [off1+off2] {sym} ptr val mem)
+       for {
+               off1 := v.AuxInt
+               sym := v.Aux
+               v_0 := v.Args[0]
+               if v_0.Op != OpPPC64ADDconst {
+                       break
+               }
+               off2 := v_0.AuxInt
+               ptr := v_0.Args[0]
+               val := v.Args[1]
+               mem := v.Args[2]
+               if !(is16Bit(off1 + off2)) {
+                       break
+               }
+               v.reset(OpPPC64FMOVDstore)
+               v.AuxInt = off1 + off2
+               v.Aux = sym
+               v.AddArg(ptr)
+               v.AddArg(val)
+               v.AddArg(mem)
+               return true
+       }
+       // match: (FMOVDstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem)
+       // cond: canMergeSym(sym1,sym2)
+       // result: (FMOVDstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
+       for {
+               off1 := v.AuxInt
+               sym1 := v.Aux
+               v_0 := v.Args[0]
+               if v_0.Op != OpPPC64MOVDaddr {
+                       break
+               }
+               off2 := v_0.AuxInt
+               sym2 := v_0.Aux
+               ptr := v_0.Args[0]
+               val := v.Args[1]
+               mem := v.Args[2]
+               if !(canMergeSym(sym1, sym2)) {
+                       break
+               }
+               v.reset(OpPPC64FMOVDstore)
+               v.AuxInt = off1 + off2
+               v.Aux = mergeSym(sym1, sym2)
+               v.AddArg(ptr)
+               v.AddArg(val)
+               v.AddArg(mem)
+               return true
+       }
+       return false
+}
+func rewriteValuePPC64_OpPPC64FMOVSload(v *Value, config *Config) bool {
+       b := v.Block
+       _ = b
+       // match: (FMOVSload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
+       // cond: canMergeSym(sym1,sym2)
+       // result: (FMOVSload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
+       for {
+               off1 := v.AuxInt
+               sym1 := v.Aux
+               v_0 := v.Args[0]
+               if v_0.Op != OpPPC64MOVDaddr {
+                       break
+               }
+               off2 := v_0.AuxInt
+               sym2 := v_0.Aux
+               ptr := v_0.Args[0]
+               mem := v.Args[1]
+               if !(canMergeSym(sym1, sym2)) {
+                       break
+               }
+               v.reset(OpPPC64FMOVSload)
+               v.AuxInt = off1 + off2
+               v.Aux = mergeSym(sym1, sym2)
+               v.AddArg(ptr)
+               v.AddArg(mem)
+               return true
+       }
+       // match: (FMOVSload [off1] {sym} (ADDconst [off2] ptr) mem)
+       // cond: is16Bit(off1+off2)
+       // result: (FMOVSload [off1+off2] {sym} ptr mem)
+       for {
+               off1 := v.AuxInt
+               sym := v.Aux
+               v_0 := v.Args[0]
+               if v_0.Op != OpPPC64ADDconst {
+                       break
+               }
+               off2 := v_0.AuxInt
+               ptr := v_0.Args[0]
+               mem := v.Args[1]
+               if !(is16Bit(off1 + off2)) {
+                       break
+               }
+               v.reset(OpPPC64FMOVSload)
+               v.AuxInt = off1 + off2
+               v.Aux = sym
+               v.AddArg(ptr)
+               v.AddArg(mem)
+               return true
+       }
+       return false
+}
+func rewriteValuePPC64_OpPPC64FMOVSstore(v *Value, config *Config) bool {
+       b := v.Block
+       _ = b
+       // match: (FMOVSstore [off1] {sym} (ADDconst [off2] ptr) val mem)
+       // cond: is16Bit(off1+off2)
+       // result: (FMOVSstore [off1+off2] {sym} ptr val mem)
+       for {
+               off1 := v.AuxInt
+               sym := v.Aux
+               v_0 := v.Args[0]
+               if v_0.Op != OpPPC64ADDconst {
+                       break
+               }
+               off2 := v_0.AuxInt
+               ptr := v_0.Args[0]
+               val := v.Args[1]
+               mem := v.Args[2]
+               if !(is16Bit(off1 + off2)) {
+                       break
+               }
+               v.reset(OpPPC64FMOVSstore)
+               v.AuxInt = off1 + off2
+               v.Aux = sym
+               v.AddArg(ptr)
+               v.AddArg(val)
+               v.AddArg(mem)
+               return true
+       }
+       // match: (FMOVSstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem)
+       // cond: canMergeSym(sym1,sym2)
+       // result: (FMOVSstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
+       for {
+               off1 := v.AuxInt
+               sym1 := v.Aux
+               v_0 := v.Args[0]
+               if v_0.Op != OpPPC64MOVDaddr {
+                       break
+               }
+               off2 := v_0.AuxInt
+               sym2 := v_0.Aux
+               ptr := v_0.Args[0]
+               val := v.Args[1]
+               mem := v.Args[2]
+               if !(canMergeSym(sym1, sym2)) {
+                       break
+               }
+               v.reset(OpPPC64FMOVSstore)
+               v.AuxInt = off1 + off2
+               v.Aux = mergeSym(sym1, sym2)
+               v.AddArg(ptr)
+               v.AddArg(val)
+               v.AddArg(mem)
+               return true
+       }
+       return false
+}
 func rewriteValuePPC64_OpPPC64GreaterEqual(v *Value, config *Config) bool {
        b := v.Block
        _ = b
@@ -4386,6 +4624,110 @@ func rewriteValuePPC64_OpPPC64LessThan(v *Value, config *Config) bool {
        }
        return false
 }
+func rewriteValuePPC64_OpPPC64MOVBZload(v *Value, config *Config) bool {
+       b := v.Block
+       _ = b
+       // match: (MOVBZload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
+       // cond: canMergeSym(sym1,sym2)
+       // result: (MOVBZload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
+       for {
+               off1 := v.AuxInt
+               sym1 := v.Aux
+               v_0 := v.Args[0]
+               if v_0.Op != OpPPC64MOVDaddr {
+                       break
+               }
+               off2 := v_0.AuxInt
+               sym2 := v_0.Aux
+               ptr := v_0.Args[0]
+               mem := v.Args[1]
+               if !(canMergeSym(sym1, sym2)) {
+                       break
+               }
+               v.reset(OpPPC64MOVBZload)
+               v.AuxInt = off1 + off2
+               v.Aux = mergeSym(sym1, sym2)
+               v.AddArg(ptr)
+               v.AddArg(mem)
+               return true
+       }
+       // match: (MOVBZload [off1] {sym} (ADDconst [off2] x) mem)
+       // cond: is16Bit(off1+off2)
+       // result: (MOVBZload [off1+off2] {sym} x mem)
+       for {
+               off1 := v.AuxInt
+               sym := v.Aux
+               v_0 := v.Args[0]
+               if v_0.Op != OpPPC64ADDconst {
+                       break
+               }
+               off2 := v_0.AuxInt
+               x := v_0.Args[0]
+               mem := v.Args[1]
+               if !(is16Bit(off1 + off2)) {
+                       break
+               }
+               v.reset(OpPPC64MOVBZload)
+               v.AuxInt = off1 + off2
+               v.Aux = sym
+               v.AddArg(x)
+               v.AddArg(mem)
+               return true
+       }
+       return false
+}
+func rewriteValuePPC64_OpPPC64MOVBload(v *Value, config *Config) bool {
+       b := v.Block
+       _ = b
+       // match: (MOVBload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
+       // cond: canMergeSym(sym1,sym2)
+       // result: (MOVBload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
+       for {
+               off1 := v.AuxInt
+               sym1 := v.Aux
+               v_0 := v.Args[0]
+               if v_0.Op != OpPPC64MOVDaddr {
+                       break
+               }
+               off2 := v_0.AuxInt
+               sym2 := v_0.Aux
+               ptr := v_0.Args[0]
+               mem := v.Args[1]
+               if !(canMergeSym(sym1, sym2)) {
+                       break
+               }
+               v.reset(OpPPC64MOVBload)
+               v.AuxInt = off1 + off2
+               v.Aux = mergeSym(sym1, sym2)
+               v.AddArg(ptr)
+               v.AddArg(mem)
+               return true
+       }
+       // match: (MOVBload [off1] {sym} (ADDconst [off2] x) mem)
+       // cond: is16Bit(off1+off2)
+       // result: (MOVBload [off1+off2] {sym} x mem)
+       for {
+               off1 := v.AuxInt
+               sym := v.Aux
+               v_0 := v.Args[0]
+               if v_0.Op != OpPPC64ADDconst {
+                       break
+               }
+               off2 := v_0.AuxInt
+               x := v_0.Args[0]
+               mem := v.Args[1]
+               if !(is16Bit(off1 + off2)) {
+                       break
+               }
+               v.reset(OpPPC64MOVBload)
+               v.AuxInt = off1 + off2
+               v.Aux = sym
+               v.AddArg(x)
+               v.AddArg(mem)
+               return true
+       }
+       return false
+}
 func rewriteValuePPC64_OpPPC64MOVBstore(v *Value, config *Config) bool {
        b := v.Block
        _ = b
@@ -4414,6 +4756,32 @@ func rewriteValuePPC64_OpPPC64MOVBstore(v *Value, config *Config) bool {
                v.AddArg(mem)
                return true
        }
+       // match: (MOVBstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem)
+       // cond: canMergeSym(sym1,sym2)
+       // result: (MOVBstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
+       for {
+               off1 := v.AuxInt
+               sym1 := v.Aux
+               v_0 := v.Args[0]
+               if v_0.Op != OpPPC64MOVDaddr {
+                       break
+               }
+               off2 := v_0.AuxInt
+               sym2 := v_0.Aux
+               ptr := v_0.Args[0]
+               val := v.Args[1]
+               mem := v.Args[2]
+               if !(canMergeSym(sym1, sym2)) {
+                       break
+               }
+               v.reset(OpPPC64MOVBstore)
+               v.AuxInt = off1 + off2
+               v.Aux = mergeSym(sym1, sym2)
+               v.AddArg(ptr)
+               v.AddArg(val)
+               v.AddArg(mem)
+               return true
+       }
        // match: (MOVBstore [off] {sym} ptr (MOVDconst [c]) mem)
        // cond: c == 0
        // result: (MOVBstorezero [off] {sym} ptr mem)
@@ -4467,6 +4835,58 @@ func rewriteValuePPC64_OpPPC64MOVBstorezero(v *Value, config *Config) bool {
        }
        return false
 }
+func rewriteValuePPC64_OpPPC64MOVDload(v *Value, config *Config) bool {
+       b := v.Block
+       _ = b
+       // match: (MOVDload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
+       // cond: canMergeSym(sym1,sym2)
+       // result: (MOVDload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
+       for {
+               off1 := v.AuxInt
+               sym1 := v.Aux
+               v_0 := v.Args[0]
+               if v_0.Op != OpPPC64MOVDaddr {
+                       break
+               }
+               off2 := v_0.AuxInt
+               sym2 := v_0.Aux
+               ptr := v_0.Args[0]
+               mem := v.Args[1]
+               if !(canMergeSym(sym1, sym2)) {
+                       break
+               }
+               v.reset(OpPPC64MOVDload)
+               v.AuxInt = off1 + off2
+               v.Aux = mergeSym(sym1, sym2)
+               v.AddArg(ptr)
+               v.AddArg(mem)
+               return true
+       }
+       // match: (MOVDload [off1] {sym} (ADDconst [off2] x) mem)
+       // cond: is16Bit(off1+off2)
+       // result: (MOVDload [off1+off2] {sym} x mem)
+       for {
+               off1 := v.AuxInt
+               sym := v.Aux
+               v_0 := v.Args[0]
+               if v_0.Op != OpPPC64ADDconst {
+                       break
+               }
+               off2 := v_0.AuxInt
+               x := v_0.Args[0]
+               mem := v.Args[1]
+               if !(is16Bit(off1 + off2)) {
+                       break
+               }
+               v.reset(OpPPC64MOVDload)
+               v.AuxInt = off1 + off2
+               v.Aux = sym
+               v.AddArg(x)
+               v.AddArg(mem)
+               return true
+       }
+       return false
+}
 func rewriteValuePPC64_OpPPC64MOVDstore(v *Value, config *Config) bool {
        b := v.Block
        _ = b
@@ -4495,6 +4915,32 @@ func rewriteValuePPC64_OpPPC64MOVDstore(v *Value, config *Config) bool {
                v.AddArg(mem)
                return true
        }
+       // match: (MOVDstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem)
+       // cond: canMergeSym(sym1,sym2)
+       // result: (MOVDstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
+       for {
+               off1 := v.AuxInt
+               sym1 := v.Aux
+               v_0 := v.Args[0]
+               if v_0.Op != OpPPC64MOVDaddr {
+                       break
+               }
+               off2 := v_0.AuxInt
+               sym2 := v_0.Aux
+               ptr := v_0.Args[0]
+               val := v.Args[1]
+               mem := v.Args[2]
+               if !(canMergeSym(sym1, sym2)) {
+                       break
+               }
+               v.reset(OpPPC64MOVDstore)
+               v.AuxInt = off1 + off2
+               v.Aux = mergeSym(sym1, sym2)
+               v.AddArg(ptr)
+               v.AddArg(val)
+               v.AddArg(mem)
+               return true
+       }
        // match: (MOVDstore [off] {sym} ptr (MOVDconst [c]) mem)
        // cond: c == 0
        // result: (MOVDstorezero [off] {sym} ptr mem)
@@ -4548,6 +4994,110 @@ func rewriteValuePPC64_OpPPC64MOVDstorezero(v *Value, config *Config) bool {
        }
        return false
 }
+func rewriteValuePPC64_OpPPC64MOVHZload(v *Value, config *Config) bool {
+       b := v.Block
+       _ = b
+       // match: (MOVHZload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
+       // cond: canMergeSym(sym1,sym2)
+       // result: (MOVHZload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
+       for {
+               off1 := v.AuxInt
+               sym1 := v.Aux
+               v_0 := v.Args[0]
+               if v_0.Op != OpPPC64MOVDaddr {
+                       break
+               }
+               off2 := v_0.AuxInt
+               sym2 := v_0.Aux
+               ptr := v_0.Args[0]
+               mem := v.Args[1]
+               if !(canMergeSym(sym1, sym2)) {
+                       break
+               }
+               v.reset(OpPPC64MOVHZload)
+               v.AuxInt = off1 + off2
+               v.Aux = mergeSym(sym1, sym2)
+               v.AddArg(ptr)
+               v.AddArg(mem)
+               return true
+       }
+       // match: (MOVHZload [off1] {sym} (ADDconst [off2] x) mem)
+       // cond: is16Bit(off1+off2)
+       // result: (MOVHZload [off1+off2] {sym} x mem)
+       for {
+               off1 := v.AuxInt
+               sym := v.Aux
+               v_0 := v.Args[0]
+               if v_0.Op != OpPPC64ADDconst {
+                       break
+               }
+               off2 := v_0.AuxInt
+               x := v_0.Args[0]
+               mem := v.Args[1]
+               if !(is16Bit(off1 + off2)) {
+                       break
+               }
+               v.reset(OpPPC64MOVHZload)
+               v.AuxInt = off1 + off2
+               v.Aux = sym
+               v.AddArg(x)
+               v.AddArg(mem)
+               return true
+       }
+       return false
+}
+func rewriteValuePPC64_OpPPC64MOVHload(v *Value, config *Config) bool {
+       b := v.Block
+       _ = b
+       // match: (MOVHload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
+       // cond: canMergeSym(sym1,sym2)
+       // result: (MOVHload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
+       for {
+               off1 := v.AuxInt
+               sym1 := v.Aux
+               v_0 := v.Args[0]
+               if v_0.Op != OpPPC64MOVDaddr {
+                       break
+               }
+               off2 := v_0.AuxInt
+               sym2 := v_0.Aux
+               ptr := v_0.Args[0]
+               mem := v.Args[1]
+               if !(canMergeSym(sym1, sym2)) {
+                       break
+               }
+               v.reset(OpPPC64MOVHload)
+               v.AuxInt = off1 + off2
+               v.Aux = mergeSym(sym1, sym2)
+               v.AddArg(ptr)
+               v.AddArg(mem)
+               return true
+       }
+       // match: (MOVHload [off1] {sym} (ADDconst [off2] x) mem)
+       // cond: is16Bit(off1+off2)
+       // result: (MOVHload [off1+off2] {sym} x mem)
+       for {
+               off1 := v.AuxInt
+               sym := v.Aux
+               v_0 := v.Args[0]
+               if v_0.Op != OpPPC64ADDconst {
+                       break
+               }
+               off2 := v_0.AuxInt
+               x := v_0.Args[0]
+               mem := v.Args[1]
+               if !(is16Bit(off1 + off2)) {
+                       break
+               }
+               v.reset(OpPPC64MOVHload)
+               v.AuxInt = off1 + off2
+               v.Aux = sym
+               v.AddArg(x)
+               v.AddArg(mem)
+               return true
+       }
+       return false
+}
 func rewriteValuePPC64_OpPPC64MOVHstore(v *Value, config *Config) bool {
        b := v.Block
        _ = b
@@ -4576,6 +5126,32 @@ func rewriteValuePPC64_OpPPC64MOVHstore(v *Value, config *Config) bool {
                v.AddArg(mem)
                return true
        }
+       // match: (MOVHstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem)
+       // cond: canMergeSym(sym1,sym2)
+       // result: (MOVHstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
+       for {
+               off1 := v.AuxInt
+               sym1 := v.Aux
+               v_0 := v.Args[0]
+               if v_0.Op != OpPPC64MOVDaddr {
+                       break
+               }
+               off2 := v_0.AuxInt
+               sym2 := v_0.Aux
+               ptr := v_0.Args[0]
+               val := v.Args[1]
+               mem := v.Args[2]
+               if !(canMergeSym(sym1, sym2)) {
+                       break
+               }
+               v.reset(OpPPC64MOVHstore)
+               v.AuxInt = off1 + off2
+               v.Aux = mergeSym(sym1, sym2)
+               v.AddArg(ptr)
+               v.AddArg(val)
+               v.AddArg(mem)
+               return true
+       }
        // match: (MOVHstore [off] {sym} ptr (MOVDconst [c]) mem)
        // cond: c == 0
        // result: (MOVHstorezero [off] {sym} ptr mem)
@@ -4629,6 +5205,110 @@ func rewriteValuePPC64_OpPPC64MOVHstorezero(v *Value, config *Config) bool {
        }
        return false
 }
+func rewriteValuePPC64_OpPPC64MOVWZload(v *Value, config *Config) bool {
+       b := v.Block
+       _ = b
+       // match: (MOVWZload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
+       // cond: canMergeSym(sym1,sym2)
+       // result: (MOVWZload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
+       for {
+               off1 := v.AuxInt
+               sym1 := v.Aux
+               v_0 := v.Args[0]
+               if v_0.Op != OpPPC64MOVDaddr {
+                       break
+               }
+               off2 := v_0.AuxInt
+               sym2 := v_0.Aux
+               ptr := v_0.Args[0]
+               mem := v.Args[1]
+               if !(canMergeSym(sym1, sym2)) {
+                       break
+               }
+               v.reset(OpPPC64MOVWZload)
+               v.AuxInt = off1 + off2
+               v.Aux = mergeSym(sym1, sym2)
+               v.AddArg(ptr)
+               v.AddArg(mem)
+               return true
+       }
+       // match: (MOVWZload [off1] {sym} (ADDconst [off2] x) mem)
+       // cond: is16Bit(off1+off2)
+       // result: (MOVWZload [off1+off2] {sym} x mem)
+       for {
+               off1 := v.AuxInt
+               sym := v.Aux
+               v_0 := v.Args[0]
+               if v_0.Op != OpPPC64ADDconst {
+                       break
+               }
+               off2 := v_0.AuxInt
+               x := v_0.Args[0]
+               mem := v.Args[1]
+               if !(is16Bit(off1 + off2)) {
+                       break
+               }
+               v.reset(OpPPC64MOVWZload)
+               v.AuxInt = off1 + off2
+               v.Aux = sym
+               v.AddArg(x)
+               v.AddArg(mem)
+               return true
+       }
+       return false
+}
+func rewriteValuePPC64_OpPPC64MOVWload(v *Value, config *Config) bool {
+       b := v.Block
+       _ = b
+       // match: (MOVWload [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) mem)
+       // cond: canMergeSym(sym1,sym2)
+       // result: (MOVWload [off1+off2] {mergeSym(sym1,sym2)} ptr mem)
+       for {
+               off1 := v.AuxInt
+               sym1 := v.Aux
+               v_0 := v.Args[0]
+               if v_0.Op != OpPPC64MOVDaddr {
+                       break
+               }
+               off2 := v_0.AuxInt
+               sym2 := v_0.Aux
+               ptr := v_0.Args[0]
+               mem := v.Args[1]
+               if !(canMergeSym(sym1, sym2)) {
+                       break
+               }
+               v.reset(OpPPC64MOVWload)
+               v.AuxInt = off1 + off2
+               v.Aux = mergeSym(sym1, sym2)
+               v.AddArg(ptr)
+               v.AddArg(mem)
+               return true
+       }
+       // match: (MOVWload [off1] {sym} (ADDconst [off2] x) mem)
+       // cond: is16Bit(off1+off2)
+       // result: (MOVWload [off1+off2] {sym} x mem)
+       for {
+               off1 := v.AuxInt
+               sym := v.Aux
+               v_0 := v.Args[0]
+               if v_0.Op != OpPPC64ADDconst {
+                       break
+               }
+               off2 := v_0.AuxInt
+               x := v_0.Args[0]
+               mem := v.Args[1]
+               if !(is16Bit(off1 + off2)) {
+                       break
+               }
+               v.reset(OpPPC64MOVWload)
+               v.AuxInt = off1 + off2
+               v.Aux = sym
+               v.AddArg(x)
+               v.AddArg(mem)
+               return true
+       }
+       return false
+}
 func rewriteValuePPC64_OpPPC64MOVWstore(v *Value, config *Config) bool {
        b := v.Block
        _ = b
@@ -4657,6 +5337,32 @@ func rewriteValuePPC64_OpPPC64MOVWstore(v *Value, config *Config) bool {
                v.AddArg(mem)
                return true
        }
+       // match: (MOVWstore [off1] {sym1} (MOVDaddr [off2] {sym2} ptr) val mem)
+       // cond: canMergeSym(sym1,sym2)
+       // result: (MOVWstore [off1+off2] {mergeSym(sym1,sym2)} ptr val mem)
+       for {
+               off1 := v.AuxInt
+               sym1 := v.Aux
+               v_0 := v.Args[0]
+               if v_0.Op != OpPPC64MOVDaddr {
+                       break
+               }
+               off2 := v_0.AuxInt
+               sym2 := v_0.Aux
+               ptr := v_0.Args[0]
+               val := v.Args[1]
+               mem := v.Args[2]
+               if !(canMergeSym(sym1, sym2)) {
+                       break
+               }
+               v.reset(OpPPC64MOVWstore)
+               v.AuxInt = off1 + off2
+               v.Aux = mergeSym(sym1, sym2)
+               v.AddArg(ptr)
+               v.AddArg(val)
+               v.AddArg(mem)
+               return true
+       }
        // match: (MOVWstore [off] {sym} ptr (MOVDconst [c]) mem)
        // cond: c == 0
        // result: (MOVWstorezero [off] {sym} ptr mem)