]> Cypherpunks.ru repositories - gostls13.git/blob - src/cmd/compile/internal/ssa/rewrite.go
[dev.typeparams] all: merge master (c8f4e61) into dev.typeparams
[gostls13.git] / src / cmd / compile / internal / ssa / rewrite.go
1 // Copyright 2015 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 package ssa
6
7 import (
8         "cmd/compile/internal/logopt"
9         "cmd/compile/internal/types"
10         "cmd/internal/obj"
11         "cmd/internal/obj/s390x"
12         "cmd/internal/objabi"
13         "cmd/internal/src"
14         "encoding/binary"
15         "fmt"
16         "io"
17         "math"
18         "math/bits"
19         "os"
20         "path/filepath"
21 )
22
23 type deadValueChoice bool
24
25 const (
26         leaveDeadValues  deadValueChoice = false
27         removeDeadValues                 = true
28 )
29
30 // deadcode indicates whether rewrite should try to remove any values that become dead.
31 func applyRewrite(f *Func, rb blockRewriter, rv valueRewriter, deadcode deadValueChoice) {
32         // repeat rewrites until we find no more rewrites
33         pendingLines := f.cachedLineStarts // Holds statement boundaries that need to be moved to a new value/block
34         pendingLines.clear()
35         debug := f.pass.debug
36         if debug > 1 {
37                 fmt.Printf("%s: rewriting for %s\n", f.pass.name, f.Name)
38         }
39         for {
40                 change := false
41                 for _, b := range f.Blocks {
42                         var b0 *Block
43                         if debug > 1 {
44                                 b0 = new(Block)
45                                 *b0 = *b
46                                 b0.Succs = append([]Edge{}, b.Succs...) // make a new copy, not aliasing
47                         }
48                         for i, c := range b.ControlValues() {
49                                 for c.Op == OpCopy {
50                                         c = c.Args[0]
51                                         b.ReplaceControl(i, c)
52                                 }
53                         }
54                         if rb(b) {
55                                 change = true
56                                 if debug > 1 {
57                                         fmt.Printf("rewriting %s  ->  %s\n", b0.LongString(), b.LongString())
58                                 }
59                         }
60                         for j, v := range b.Values {
61                                 var v0 *Value
62                                 if debug > 1 {
63                                         v0 = new(Value)
64                                         *v0 = *v
65                                         v0.Args = append([]*Value{}, v.Args...) // make a new copy, not aliasing
66                                 }
67                                 if v.Uses == 0 && v.removeable() {
68                                         if v.Op != OpInvalid && deadcode == removeDeadValues {
69                                                 // Reset any values that are now unused, so that we decrement
70                                                 // the use count of all of its arguments.
71                                                 // Not quite a deadcode pass, because it does not handle cycles.
72                                                 // But it should help Uses==1 rules to fire.
73                                                 v.reset(OpInvalid)
74                                                 change = true
75                                         }
76                                         // No point rewriting values which aren't used.
77                                         continue
78                                 }
79
80                                 vchange := phielimValue(v)
81                                 if vchange && debug > 1 {
82                                         fmt.Printf("rewriting %s  ->  %s\n", v0.LongString(), v.LongString())
83                                 }
84
85                                 // Eliminate copy inputs.
86                                 // If any copy input becomes unused, mark it
87                                 // as invalid and discard its argument. Repeat
88                                 // recursively on the discarded argument.
89                                 // This phase helps remove phantom "dead copy" uses
90                                 // of a value so that a x.Uses==1 rule condition
91                                 // fires reliably.
92                                 for i, a := range v.Args {
93                                         if a.Op != OpCopy {
94                                                 continue
95                                         }
96                                         aa := copySource(a)
97                                         v.SetArg(i, aa)
98                                         // If a, a copy, has a line boundary indicator, attempt to find a new value
99                                         // to hold it.  The first candidate is the value that will replace a (aa),
100                                         // if it shares the same block and line and is eligible.
101                                         // The second option is v, which has a as an input.  Because aa is earlier in
102                                         // the data flow, it is the better choice.
103                                         if a.Pos.IsStmt() == src.PosIsStmt {
104                                                 if aa.Block == a.Block && aa.Pos.Line() == a.Pos.Line() && aa.Pos.IsStmt() != src.PosNotStmt {
105                                                         aa.Pos = aa.Pos.WithIsStmt()
106                                                 } else if v.Block == a.Block && v.Pos.Line() == a.Pos.Line() && v.Pos.IsStmt() != src.PosNotStmt {
107                                                         v.Pos = v.Pos.WithIsStmt()
108                                                 } else {
109                                                         // Record the lost line and look for a new home after all rewrites are complete.
110                                                         // TODO: it's possible (in FOR loops, in particular) for statement boundaries for the same
111                                                         // line to appear in more than one block, but only one block is stored, so if both end
112                                                         // up here, then one will be lost.
113                                                         pendingLines.set(a.Pos, int32(a.Block.ID))
114                                                 }
115                                                 a.Pos = a.Pos.WithNotStmt()
116                                         }
117                                         vchange = true
118                                         for a.Uses == 0 {
119                                                 b := a.Args[0]
120                                                 a.reset(OpInvalid)
121                                                 a = b
122                                         }
123                                 }
124                                 if vchange && debug > 1 {
125                                         fmt.Printf("rewriting %s  ->  %s\n", v0.LongString(), v.LongString())
126                                 }
127
128                                 // apply rewrite function
129                                 if rv(v) {
130                                         vchange = true
131                                         // If value changed to a poor choice for a statement boundary, move the boundary
132                                         if v.Pos.IsStmt() == src.PosIsStmt {
133                                                 if k := nextGoodStatementIndex(v, j, b); k != j {
134                                                         v.Pos = v.Pos.WithNotStmt()
135                                                         b.Values[k].Pos = b.Values[k].Pos.WithIsStmt()
136                                                 }
137                                         }
138                                 }
139
140                                 change = change || vchange
141                                 if vchange && debug > 1 {
142                                         fmt.Printf("rewriting %s  ->  %s\n", v0.LongString(), v.LongString())
143                                 }
144                         }
145                 }
146                 if !change {
147                         break
148                 }
149         }
150         // remove clobbered values
151         for _, b := range f.Blocks {
152                 j := 0
153                 for i, v := range b.Values {
154                         vl := v.Pos
155                         if v.Op == OpInvalid {
156                                 if v.Pos.IsStmt() == src.PosIsStmt {
157                                         pendingLines.set(vl, int32(b.ID))
158                                 }
159                                 f.freeValue(v)
160                                 continue
161                         }
162                         if v.Pos.IsStmt() != src.PosNotStmt && !notStmtBoundary(v.Op) && pendingLines.get(vl) == int32(b.ID) {
163                                 pendingLines.remove(vl)
164                                 v.Pos = v.Pos.WithIsStmt()
165                         }
166                         if i != j {
167                                 b.Values[j] = v
168                         }
169                         j++
170                 }
171                 if pendingLines.get(b.Pos) == int32(b.ID) {
172                         b.Pos = b.Pos.WithIsStmt()
173                         pendingLines.remove(b.Pos)
174                 }
175                 b.truncateValues(j)
176         }
177 }
178
179 // Common functions called from rewriting rules
180
181 func is64BitFloat(t *types.Type) bool {
182         return t.Size() == 8 && t.IsFloat()
183 }
184
185 func is32BitFloat(t *types.Type) bool {
186         return t.Size() == 4 && t.IsFloat()
187 }
188
189 func is64BitInt(t *types.Type) bool {
190         return t.Size() == 8 && t.IsInteger()
191 }
192
193 func is32BitInt(t *types.Type) bool {
194         return t.Size() == 4 && t.IsInteger()
195 }
196
197 func is16BitInt(t *types.Type) bool {
198         return t.Size() == 2 && t.IsInteger()
199 }
200
201 func is8BitInt(t *types.Type) bool {
202         return t.Size() == 1 && t.IsInteger()
203 }
204
205 func isPtr(t *types.Type) bool {
206         return t.IsPtrShaped()
207 }
208
209 func isSigned(t *types.Type) bool {
210         return t.IsSigned()
211 }
212
213 // mergeSym merges two symbolic offsets. There is no real merging of
214 // offsets, we just pick the non-nil one.
215 func mergeSym(x, y Sym) Sym {
216         if x == nil {
217                 return y
218         }
219         if y == nil {
220                 return x
221         }
222         panic(fmt.Sprintf("mergeSym with two non-nil syms %v %v", x, y))
223 }
224
225 func canMergeSym(x, y Sym) bool {
226         return x == nil || y == nil
227 }
228
229 // canMergeLoadClobber reports whether the load can be merged into target without
230 // invalidating the schedule.
231 // It also checks that the other non-load argument x is something we
232 // are ok with clobbering.
233 func canMergeLoadClobber(target, load, x *Value) bool {
234         // The register containing x is going to get clobbered.
235         // Don't merge if we still need the value of x.
236         // We don't have liveness information here, but we can
237         // approximate x dying with:
238         //  1) target is x's only use.
239         //  2) target is not in a deeper loop than x.
240         if x.Uses != 1 {
241                 return false
242         }
243         loopnest := x.Block.Func.loopnest()
244         loopnest.calculateDepths()
245         if loopnest.depth(target.Block.ID) > loopnest.depth(x.Block.ID) {
246                 return false
247         }
248         return canMergeLoad(target, load)
249 }
250
251 // canMergeLoad reports whether the load can be merged into target without
252 // invalidating the schedule.
253 func canMergeLoad(target, load *Value) bool {
254         if target.Block.ID != load.Block.ID {
255                 // If the load is in a different block do not merge it.
256                 return false
257         }
258
259         // We can't merge the load into the target if the load
260         // has more than one use.
261         if load.Uses != 1 {
262                 return false
263         }
264
265         mem := load.MemoryArg()
266
267         // We need the load's memory arg to still be alive at target. That
268         // can't be the case if one of target's args depends on a memory
269         // state that is a successor of load's memory arg.
270         //
271         // For example, it would be invalid to merge load into target in
272         // the following situation because newmem has killed oldmem
273         // before target is reached:
274         //     load = read ... oldmem
275         //   newmem = write ... oldmem
276         //     arg0 = read ... newmem
277         //   target = add arg0 load
278         //
279         // If the argument comes from a different block then we can exclude
280         // it immediately because it must dominate load (which is in the
281         // same block as target).
282         var args []*Value
283         for _, a := range target.Args {
284                 if a != load && a.Block.ID == target.Block.ID {
285                         args = append(args, a)
286                 }
287         }
288
289         // memPreds contains memory states known to be predecessors of load's
290         // memory state. It is lazily initialized.
291         var memPreds map[*Value]bool
292         for i := 0; len(args) > 0; i++ {
293                 const limit = 100
294                 if i >= limit {
295                         // Give up if we have done a lot of iterations.
296                         return false
297                 }
298                 v := args[len(args)-1]
299                 args = args[:len(args)-1]
300                 if target.Block.ID != v.Block.ID {
301                         // Since target and load are in the same block
302                         // we can stop searching when we leave the block.
303                         continue
304                 }
305                 if v.Op == OpPhi {
306                         // A Phi implies we have reached the top of the block.
307                         // The memory phi, if it exists, is always
308                         // the first logical store in the block.
309                         continue
310                 }
311                 if v.Type.IsTuple() && v.Type.FieldType(1).IsMemory() {
312                         // We could handle this situation however it is likely
313                         // to be very rare.
314                         return false
315                 }
316                 if v.Op.SymEffect()&SymAddr != 0 {
317                         // This case prevents an operation that calculates the
318                         // address of a local variable from being forced to schedule
319                         // before its corresponding VarDef.
320                         // See issue 28445.
321                         //   v1 = LOAD ...
322                         //   v2 = VARDEF
323                         //   v3 = LEAQ
324                         //   v4 = CMPQ v1 v3
325                         // We don't want to combine the CMPQ with the load, because
326                         // that would force the CMPQ to schedule before the VARDEF, which
327                         // in turn requires the LEAQ to schedule before the VARDEF.
328                         return false
329                 }
330                 if v.Type.IsMemory() {
331                         if memPreds == nil {
332                                 // Initialise a map containing memory states
333                                 // known to be predecessors of load's memory
334                                 // state.
335                                 memPreds = make(map[*Value]bool)
336                                 m := mem
337                                 const limit = 50
338                                 for i := 0; i < limit; i++ {
339                                         if m.Op == OpPhi {
340                                                 // The memory phi, if it exists, is always
341                                                 // the first logical store in the block.
342                                                 break
343                                         }
344                                         if m.Block.ID != target.Block.ID {
345                                                 break
346                                         }
347                                         if !m.Type.IsMemory() {
348                                                 break
349                                         }
350                                         memPreds[m] = true
351                                         if len(m.Args) == 0 {
352                                                 break
353                                         }
354                                         m = m.MemoryArg()
355                                 }
356                         }
357
358                         // We can merge if v is a predecessor of mem.
359                         //
360                         // For example, we can merge load into target in the
361                         // following scenario:
362                         //      x = read ... v
363                         //    mem = write ... v
364                         //   load = read ... mem
365                         // target = add x load
366                         if memPreds[v] {
367                                 continue
368                         }
369                         return false
370                 }
371                 if len(v.Args) > 0 && v.Args[len(v.Args)-1] == mem {
372                         // If v takes mem as an input then we know mem
373                         // is valid at this point.
374                         continue
375                 }
376                 for _, a := range v.Args {
377                         if target.Block.ID == a.Block.ID {
378                                 args = append(args, a)
379                         }
380                 }
381         }
382
383         return true
384 }
385
386 // isSameCall reports whether sym is the same as the given named symbol
387 func isSameCall(sym interface{}, name string) bool {
388         fn := sym.(*AuxCall).Fn
389         return fn != nil && fn.String() == name
390 }
391
392 // nlz returns the number of leading zeros.
393 func nlz64(x int64) int { return bits.LeadingZeros64(uint64(x)) }
394 func nlz32(x int32) int { return bits.LeadingZeros32(uint32(x)) }
395 func nlz16(x int16) int { return bits.LeadingZeros16(uint16(x)) }
396 func nlz8(x int8) int   { return bits.LeadingZeros8(uint8(x)) }
397
398 // ntzX returns the number of trailing zeros.
399 func ntz64(x int64) int { return bits.TrailingZeros64(uint64(x)) }
400 func ntz32(x int32) int { return bits.TrailingZeros32(uint32(x)) }
401 func ntz16(x int16) int { return bits.TrailingZeros16(uint16(x)) }
402 func ntz8(x int8) int   { return bits.TrailingZeros8(uint8(x)) }
403
404 func oneBit(x int64) bool   { return x&(x-1) == 0 && x != 0 }
405 func oneBit8(x int8) bool   { return x&(x-1) == 0 && x != 0 }
406 func oneBit16(x int16) bool { return x&(x-1) == 0 && x != 0 }
407 func oneBit32(x int32) bool { return x&(x-1) == 0 && x != 0 }
408 func oneBit64(x int64) bool { return x&(x-1) == 0 && x != 0 }
409
410 // nto returns the number of trailing ones.
411 func nto(x int64) int64 {
412         return int64(ntz64(^x))
413 }
414
415 // logX returns logarithm of n base 2.
416 // n must be a positive power of 2 (isPowerOfTwoX returns true).
417 func log8(n int8) int64 {
418         return int64(bits.Len8(uint8(n))) - 1
419 }
420 func log16(n int16) int64 {
421         return int64(bits.Len16(uint16(n))) - 1
422 }
423 func log32(n int32) int64 {
424         return int64(bits.Len32(uint32(n))) - 1
425 }
426 func log64(n int64) int64 {
427         return int64(bits.Len64(uint64(n))) - 1
428 }
429
430 // log2uint32 returns logarithm in base 2 of uint32(n), with log2(0) = -1.
431 // Rounds down.
432 func log2uint32(n int64) int64 {
433         return int64(bits.Len32(uint32(n))) - 1
434 }
435
436 // isPowerOfTwo functions report whether n is a power of 2.
437 func isPowerOfTwo8(n int8) bool {
438         return n > 0 && n&(n-1) == 0
439 }
440 func isPowerOfTwo16(n int16) bool {
441         return n > 0 && n&(n-1) == 0
442 }
443 func isPowerOfTwo32(n int32) bool {
444         return n > 0 && n&(n-1) == 0
445 }
446 func isPowerOfTwo64(n int64) bool {
447         return n > 0 && n&(n-1) == 0
448 }
449
450 // isUint64PowerOfTwo reports whether uint64(n) is a power of 2.
451 func isUint64PowerOfTwo(in int64) bool {
452         n := uint64(in)
453         return n > 0 && n&(n-1) == 0
454 }
455
456 // isUint32PowerOfTwo reports whether uint32(n) is a power of 2.
457 func isUint32PowerOfTwo(in int64) bool {
458         n := uint64(uint32(in))
459         return n > 0 && n&(n-1) == 0
460 }
461
462 // is32Bit reports whether n can be represented as a signed 32 bit integer.
463 func is32Bit(n int64) bool {
464         return n == int64(int32(n))
465 }
466
467 // is16Bit reports whether n can be represented as a signed 16 bit integer.
468 func is16Bit(n int64) bool {
469         return n == int64(int16(n))
470 }
471
472 // is8Bit reports whether n can be represented as a signed 8 bit integer.
473 func is8Bit(n int64) bool {
474         return n == int64(int8(n))
475 }
476
477 // isU8Bit reports whether n can be represented as an unsigned 8 bit integer.
478 func isU8Bit(n int64) bool {
479         return n == int64(uint8(n))
480 }
481
482 // isU12Bit reports whether n can be represented as an unsigned 12 bit integer.
483 func isU12Bit(n int64) bool {
484         return 0 <= n && n < (1<<12)
485 }
486
487 // isU16Bit reports whether n can be represented as an unsigned 16 bit integer.
488 func isU16Bit(n int64) bool {
489         return n == int64(uint16(n))
490 }
491
492 // isU32Bit reports whether n can be represented as an unsigned 32 bit integer.
493 func isU32Bit(n int64) bool {
494         return n == int64(uint32(n))
495 }
496
497 // is20Bit reports whether n can be represented as a signed 20 bit integer.
498 func is20Bit(n int64) bool {
499         return -(1<<19) <= n && n < (1<<19)
500 }
501
502 // b2i translates a boolean value to 0 or 1 for assigning to auxInt.
503 func b2i(b bool) int64 {
504         if b {
505                 return 1
506         }
507         return 0
508 }
509
510 // b2i32 translates a boolean value to 0 or 1.
511 func b2i32(b bool) int32 {
512         if b {
513                 return 1
514         }
515         return 0
516 }
517
518 // shiftIsBounded reports whether (left/right) shift Value v is known to be bounded.
519 // A shift is bounded if it is shifting by less than the width of the shifted value.
520 func shiftIsBounded(v *Value) bool {
521         return v.AuxInt != 0
522 }
523
524 // canonLessThan returns whether x is "ordered" less than y, for purposes of normalizing
525 // generated code as much as possible.
526 func canonLessThan(x, y *Value) bool {
527         if x.Op != y.Op {
528                 return x.Op < y.Op
529         }
530         if !x.Pos.SameFileAndLine(y.Pos) {
531                 return x.Pos.Before(y.Pos)
532         }
533         return x.ID < y.ID
534 }
535
536 // truncate64Fto32F converts a float64 value to a float32 preserving the bit pattern
537 // of the mantissa. It will panic if the truncation results in lost information.
538 func truncate64Fto32F(f float64) float32 {
539         if !isExactFloat32(f) {
540                 panic("truncate64Fto32F: truncation is not exact")
541         }
542         if !math.IsNaN(f) {
543                 return float32(f)
544         }
545         // NaN bit patterns aren't necessarily preserved across conversion
546         // instructions so we need to do the conversion manually.
547         b := math.Float64bits(f)
548         m := b & ((1 << 52) - 1) // mantissa (a.k.a. significand)
549         //          | sign                  | exponent   | mantissa       |
550         r := uint32(((b >> 32) & (1 << 31)) | 0x7f800000 | (m >> (52 - 23)))
551         return math.Float32frombits(r)
552 }
553
554 // extend32Fto64F converts a float32 value to a float64 value preserving the bit
555 // pattern of the mantissa.
556 func extend32Fto64F(f float32) float64 {
557         if !math.IsNaN(float64(f)) {
558                 return float64(f)
559         }
560         // NaN bit patterns aren't necessarily preserved across conversion
561         // instructions so we need to do the conversion manually.
562         b := uint64(math.Float32bits(f))
563         //   | sign                  | exponent      | mantissa                    |
564         r := ((b << 32) & (1 << 63)) | (0x7ff << 52) | ((b & 0x7fffff) << (52 - 23))
565         return math.Float64frombits(r)
566 }
567
568 // DivisionNeedsFixUp reports whether the division needs fix-up code.
569 func DivisionNeedsFixUp(v *Value) bool {
570         return v.AuxInt == 0
571 }
572
573 // auxFrom64F encodes a float64 value so it can be stored in an AuxInt.
574 func auxFrom64F(f float64) int64 {
575         if f != f {
576                 panic("can't encode a NaN in AuxInt field")
577         }
578         return int64(math.Float64bits(f))
579 }
580
581 // auxFrom32F encodes a float32 value so it can be stored in an AuxInt.
582 func auxFrom32F(f float32) int64 {
583         if f != f {
584                 panic("can't encode a NaN in AuxInt field")
585         }
586         return int64(math.Float64bits(extend32Fto64F(f)))
587 }
588
589 // auxTo32F decodes a float32 from the AuxInt value provided.
590 func auxTo32F(i int64) float32 {
591         return truncate64Fto32F(math.Float64frombits(uint64(i)))
592 }
593
594 // auxTo64F decodes a float64 from the AuxInt value provided.
595 func auxTo64F(i int64) float64 {
596         return math.Float64frombits(uint64(i))
597 }
598
599 func auxIntToBool(i int64) bool {
600         if i == 0 {
601                 return false
602         }
603         return true
604 }
605 func auxIntToInt8(i int64) int8 {
606         return int8(i)
607 }
608 func auxIntToInt16(i int64) int16 {
609         return int16(i)
610 }
611 func auxIntToInt32(i int64) int32 {
612         return int32(i)
613 }
614 func auxIntToInt64(i int64) int64 {
615         return i
616 }
617 func auxIntToUint8(i int64) uint8 {
618         return uint8(i)
619 }
620 func auxIntToFloat32(i int64) float32 {
621         return float32(math.Float64frombits(uint64(i)))
622 }
623 func auxIntToFloat64(i int64) float64 {
624         return math.Float64frombits(uint64(i))
625 }
626 func auxIntToValAndOff(i int64) ValAndOff {
627         return ValAndOff(i)
628 }
629 func auxIntToArm64BitField(i int64) arm64BitField {
630         return arm64BitField(i)
631 }
632 func auxIntToInt128(x int64) int128 {
633         if x != 0 {
634                 panic("nonzero int128 not allowed")
635         }
636         return 0
637 }
638 func auxIntToFlagConstant(x int64) flagConstant {
639         return flagConstant(x)
640 }
641
642 func auxIntToOp(cc int64) Op {
643         return Op(cc)
644 }
645
646 func boolToAuxInt(b bool) int64 {
647         if b {
648                 return 1
649         }
650         return 0
651 }
652 func int8ToAuxInt(i int8) int64 {
653         return int64(i)
654 }
655 func int16ToAuxInt(i int16) int64 {
656         return int64(i)
657 }
658 func int32ToAuxInt(i int32) int64 {
659         return int64(i)
660 }
661 func int64ToAuxInt(i int64) int64 {
662         return int64(i)
663 }
664 func uint8ToAuxInt(i uint8) int64 {
665         return int64(int8(i))
666 }
667 func float32ToAuxInt(f float32) int64 {
668         return int64(math.Float64bits(float64(f)))
669 }
670 func float64ToAuxInt(f float64) int64 {
671         return int64(math.Float64bits(f))
672 }
673 func valAndOffToAuxInt(v ValAndOff) int64 {
674         return int64(v)
675 }
676 func arm64BitFieldToAuxInt(v arm64BitField) int64 {
677         return int64(v)
678 }
679 func int128ToAuxInt(x int128) int64 {
680         if x != 0 {
681                 panic("nonzero int128 not allowed")
682         }
683         return 0
684 }
685 func flagConstantToAuxInt(x flagConstant) int64 {
686         return int64(x)
687 }
688
689 func opToAuxInt(o Op) int64 {
690         return int64(o)
691 }
692
693 // Aux is an interface to hold miscellaneous data in Blocks and Values.
694 type Aux interface {
695         CanBeAnSSAAux()
696 }
697
698 // stringAux wraps string values for use in Aux.
699 type stringAux string
700
701 func (stringAux) CanBeAnSSAAux() {}
702
703 func auxToString(i Aux) string {
704         return string(i.(stringAux))
705 }
706 func auxToSym(i Aux) Sym {
707         // TODO: kind of a hack - allows nil interface through
708         s, _ := i.(Sym)
709         return s
710 }
711 func auxToType(i Aux) *types.Type {
712         return i.(*types.Type)
713 }
714 func auxToCall(i Aux) *AuxCall {
715         return i.(*AuxCall)
716 }
717 func auxToS390xCCMask(i Aux) s390x.CCMask {
718         return i.(s390x.CCMask)
719 }
720 func auxToS390xRotateParams(i Aux) s390x.RotateParams {
721         return i.(s390x.RotateParams)
722 }
723
724 func StringToAux(s string) Aux {
725         return stringAux(s)
726 }
727 func symToAux(s Sym) Aux {
728         return s
729 }
730 func callToAux(s *AuxCall) Aux {
731         return s
732 }
733 func typeToAux(t *types.Type) Aux {
734         return t
735 }
736 func s390xCCMaskToAux(c s390x.CCMask) Aux {
737         return c
738 }
739 func s390xRotateParamsToAux(r s390x.RotateParams) Aux {
740         return r
741 }
742
743 // uaddOvf reports whether unsigned a+b would overflow.
744 func uaddOvf(a, b int64) bool {
745         return uint64(a)+uint64(b) < uint64(a)
746 }
747
748 // loadLSymOffset simulates reading a word at an offset into a
749 // read-only symbol's runtime memory. If it would read a pointer to
750 // another symbol, that symbol is returned. Otherwise, it returns nil.
751 func loadLSymOffset(lsym *obj.LSym, offset int64) *obj.LSym {
752         if lsym.Type != objabi.SRODATA {
753                 return nil
754         }
755
756         for _, r := range lsym.R {
757                 if int64(r.Off) == offset && r.Type&^objabi.R_WEAK == objabi.R_ADDR && r.Add == 0 {
758                         return r.Sym
759                 }
760         }
761
762         return nil
763 }
764
765 // de-virtualize an InterLECall
766 // 'sym' is the symbol for the itab
767 func devirtLESym(v *Value, aux Aux, sym Sym, offset int64) *obj.LSym {
768         n, ok := sym.(*obj.LSym)
769         if !ok {
770                 return nil
771         }
772
773         lsym := loadLSymOffset(n, offset)
774         if f := v.Block.Func; f.pass.debug > 0 {
775                 if lsym != nil {
776                         f.Warnl(v.Pos, "de-virtualizing call")
777                 } else {
778                         f.Warnl(v.Pos, "couldn't de-virtualize call")
779                 }
780         }
781         return lsym
782 }
783
784 func devirtLECall(v *Value, sym *obj.LSym) *Value {
785         v.Op = OpStaticLECall
786         auxcall := v.Aux.(*AuxCall)
787         auxcall.Fn = sym
788         v.RemoveArg(0)
789         return v
790 }
791
792 // isSamePtr reports whether p1 and p2 point to the same address.
793 func isSamePtr(p1, p2 *Value) bool {
794         if p1 == p2 {
795                 return true
796         }
797         if p1.Op != p2.Op {
798                 return false
799         }
800         switch p1.Op {
801         case OpOffPtr:
802                 return p1.AuxInt == p2.AuxInt && isSamePtr(p1.Args[0], p2.Args[0])
803         case OpAddr, OpLocalAddr:
804                 // OpAddr's 0th arg is either OpSP or OpSB, which means that it is uniquely identified by its Op.
805                 // Checking for value equality only works after [z]cse has run.
806                 return p1.Aux == p2.Aux && p1.Args[0].Op == p2.Args[0].Op
807         case OpAddPtr:
808                 return p1.Args[1] == p2.Args[1] && isSamePtr(p1.Args[0], p2.Args[0])
809         }
810         return false
811 }
812
813 func isStackPtr(v *Value) bool {
814         for v.Op == OpOffPtr || v.Op == OpAddPtr {
815                 v = v.Args[0]
816         }
817         return v.Op == OpSP || v.Op == OpLocalAddr
818 }
819
820 // disjoint reports whether the memory region specified by [p1:p1+n1)
821 // does not overlap with [p2:p2+n2).
822 // A return value of false does not imply the regions overlap.
823 func disjoint(p1 *Value, n1 int64, p2 *Value, n2 int64) bool {
824         if n1 == 0 || n2 == 0 {
825                 return true
826         }
827         if p1 == p2 {
828                 return false
829         }
830         baseAndOffset := func(ptr *Value) (base *Value, offset int64) {
831                 base, offset = ptr, 0
832                 for base.Op == OpOffPtr {
833                         offset += base.AuxInt
834                         base = base.Args[0]
835                 }
836                 return base, offset
837         }
838         p1, off1 := baseAndOffset(p1)
839         p2, off2 := baseAndOffset(p2)
840         if isSamePtr(p1, p2) {
841                 return !overlap(off1, n1, off2, n2)
842         }
843         // p1 and p2 are not the same, so if they are both OpAddrs then
844         // they point to different variables.
845         // If one pointer is on the stack and the other is an argument
846         // then they can't overlap.
847         switch p1.Op {
848         case OpAddr, OpLocalAddr:
849                 if p2.Op == OpAddr || p2.Op == OpLocalAddr || p2.Op == OpSP {
850                         return true
851                 }
852                 return (p2.Op == OpArg || p2.Op == OpArgIntReg) && p1.Args[0].Op == OpSP
853         case OpArg, OpArgIntReg:
854                 if p2.Op == OpSP || p2.Op == OpLocalAddr {
855                         return true
856                 }
857         case OpSP:
858                 return p2.Op == OpAddr || p2.Op == OpLocalAddr || p2.Op == OpArg || p2.Op == OpArgIntReg || p2.Op == OpSP
859         }
860         return false
861 }
862
863 // moveSize returns the number of bytes an aligned MOV instruction moves
864 func moveSize(align int64, c *Config) int64 {
865         switch {
866         case align%8 == 0 && c.PtrSize == 8:
867                 return 8
868         case align%4 == 0:
869                 return 4
870         case align%2 == 0:
871                 return 2
872         }
873         return 1
874 }
875
876 // mergePoint finds a block among a's blocks which dominates b and is itself
877 // dominated by all of a's blocks. Returns nil if it can't find one.
878 // Might return nil even if one does exist.
879 func mergePoint(b *Block, a ...*Value) *Block {
880         // Walk backward from b looking for one of the a's blocks.
881
882         // Max distance
883         d := 100
884
885         for d > 0 {
886                 for _, x := range a {
887                         if b == x.Block {
888                                 goto found
889                         }
890                 }
891                 if len(b.Preds) > 1 {
892                         // Don't know which way to go back. Abort.
893                         return nil
894                 }
895                 b = b.Preds[0].b
896                 d--
897         }
898         return nil // too far away
899 found:
900         // At this point, r is the first value in a that we find by walking backwards.
901         // if we return anything, r will be it.
902         r := b
903
904         // Keep going, counting the other a's that we find. They must all dominate r.
905         na := 0
906         for d > 0 {
907                 for _, x := range a {
908                         if b == x.Block {
909                                 na++
910                         }
911                 }
912                 if na == len(a) {
913                         // Found all of a in a backwards walk. We can return r.
914                         return r
915                 }
916                 if len(b.Preds) > 1 {
917                         return nil
918                 }
919                 b = b.Preds[0].b
920                 d--
921
922         }
923         return nil // too far away
924 }
925
926 // clobber invalidates values. Returns true.
927 // clobber is used by rewrite rules to:
928 //   A) make sure the values are really dead and never used again.
929 //   B) decrement use counts of the values' args.
930 func clobber(vv ...*Value) bool {
931         for _, v := range vv {
932                 v.reset(OpInvalid)
933                 // Note: leave v.Block intact.  The Block field is used after clobber.
934         }
935         return true
936 }
937
938 // clobberIfDead resets v when use count is 1. Returns true.
939 // clobberIfDead is used by rewrite rules to decrement
940 // use counts of v's args when v is dead and never used.
941 func clobberIfDead(v *Value) bool {
942         if v.Uses == 1 {
943                 v.reset(OpInvalid)
944         }
945         // Note: leave v.Block intact.  The Block field is used after clobberIfDead.
946         return true
947 }
948
949 // noteRule is an easy way to track if a rule is matched when writing
950 // new ones.  Make the rule of interest also conditional on
951 //     noteRule("note to self: rule of interest matched")
952 // and that message will print when the rule matches.
953 func noteRule(s string) bool {
954         fmt.Println(s)
955         return true
956 }
957
958 // countRule increments Func.ruleMatches[key].
959 // If Func.ruleMatches is non-nil at the end
960 // of compilation, it will be printed to stdout.
961 // This is intended to make it easier to find which functions
962 // which contain lots of rules matches when developing new rules.
963 func countRule(v *Value, key string) bool {
964         f := v.Block.Func
965         if f.ruleMatches == nil {
966                 f.ruleMatches = make(map[string]int)
967         }
968         f.ruleMatches[key]++
969         return true
970 }
971
972 // warnRule generates compiler debug output with string s when
973 // v is not in autogenerated code, cond is true and the rule has fired.
974 func warnRule(cond bool, v *Value, s string) bool {
975         if pos := v.Pos; pos.Line() > 1 && cond {
976                 v.Block.Func.Warnl(pos, s)
977         }
978         return true
979 }
980
981 // for a pseudo-op like (LessThan x), extract x
982 func flagArg(v *Value) *Value {
983         if len(v.Args) != 1 || !v.Args[0].Type.IsFlags() {
984                 return nil
985         }
986         return v.Args[0]
987 }
988
989 // arm64Negate finds the complement to an ARM64 condition code,
990 // for example !Equal -> NotEqual or !LessThan -> GreaterEqual
991 //
992 // For floating point, it's more subtle because NaN is unordered. We do
993 // !LessThanF -> NotLessThanF, the latter takes care of NaNs.
994 func arm64Negate(op Op) Op {
995         switch op {
996         case OpARM64LessThan:
997                 return OpARM64GreaterEqual
998         case OpARM64LessThanU:
999                 return OpARM64GreaterEqualU
1000         case OpARM64GreaterThan:
1001                 return OpARM64LessEqual
1002         case OpARM64GreaterThanU:
1003                 return OpARM64LessEqualU
1004         case OpARM64LessEqual:
1005                 return OpARM64GreaterThan
1006         case OpARM64LessEqualU:
1007                 return OpARM64GreaterThanU
1008         case OpARM64GreaterEqual:
1009                 return OpARM64LessThan
1010         case OpARM64GreaterEqualU:
1011                 return OpARM64LessThanU
1012         case OpARM64Equal:
1013                 return OpARM64NotEqual
1014         case OpARM64NotEqual:
1015                 return OpARM64Equal
1016         case OpARM64LessThanF:
1017                 return OpARM64NotLessThanF
1018         case OpARM64NotLessThanF:
1019                 return OpARM64LessThanF
1020         case OpARM64LessEqualF:
1021                 return OpARM64NotLessEqualF
1022         case OpARM64NotLessEqualF:
1023                 return OpARM64LessEqualF
1024         case OpARM64GreaterThanF:
1025                 return OpARM64NotGreaterThanF
1026         case OpARM64NotGreaterThanF:
1027                 return OpARM64GreaterThanF
1028         case OpARM64GreaterEqualF:
1029                 return OpARM64NotGreaterEqualF
1030         case OpARM64NotGreaterEqualF:
1031                 return OpARM64GreaterEqualF
1032         default:
1033                 panic("unreachable")
1034         }
1035 }
1036
1037 // arm64Invert evaluates (InvertFlags op), which
1038 // is the same as altering the condition codes such
1039 // that the same result would be produced if the arguments
1040 // to the flag-generating instruction were reversed, e.g.
1041 // (InvertFlags (CMP x y)) -> (CMP y x)
1042 func arm64Invert(op Op) Op {
1043         switch op {
1044         case OpARM64LessThan:
1045                 return OpARM64GreaterThan
1046         case OpARM64LessThanU:
1047                 return OpARM64GreaterThanU
1048         case OpARM64GreaterThan:
1049                 return OpARM64LessThan
1050         case OpARM64GreaterThanU:
1051                 return OpARM64LessThanU
1052         case OpARM64LessEqual:
1053                 return OpARM64GreaterEqual
1054         case OpARM64LessEqualU:
1055                 return OpARM64GreaterEqualU
1056         case OpARM64GreaterEqual:
1057                 return OpARM64LessEqual
1058         case OpARM64GreaterEqualU:
1059                 return OpARM64LessEqualU
1060         case OpARM64Equal, OpARM64NotEqual:
1061                 return op
1062         case OpARM64LessThanF:
1063                 return OpARM64GreaterThanF
1064         case OpARM64GreaterThanF:
1065                 return OpARM64LessThanF
1066         case OpARM64LessEqualF:
1067                 return OpARM64GreaterEqualF
1068         case OpARM64GreaterEqualF:
1069                 return OpARM64LessEqualF
1070         case OpARM64NotLessThanF:
1071                 return OpARM64NotGreaterThanF
1072         case OpARM64NotGreaterThanF:
1073                 return OpARM64NotLessThanF
1074         case OpARM64NotLessEqualF:
1075                 return OpARM64NotGreaterEqualF
1076         case OpARM64NotGreaterEqualF:
1077                 return OpARM64NotLessEqualF
1078         default:
1079                 panic("unreachable")
1080         }
1081 }
1082
1083 // evaluate an ARM64 op against a flags value
1084 // that is potentially constant; return 1 for true,
1085 // -1 for false, and 0 for not constant.
1086 func ccARM64Eval(op Op, flags *Value) int {
1087         fop := flags.Op
1088         if fop == OpARM64InvertFlags {
1089                 return -ccARM64Eval(op, flags.Args[0])
1090         }
1091         if fop != OpARM64FlagConstant {
1092                 return 0
1093         }
1094         fc := flagConstant(flags.AuxInt)
1095         b2i := func(b bool) int {
1096                 if b {
1097                         return 1
1098                 }
1099                 return -1
1100         }
1101         switch op {
1102         case OpARM64Equal:
1103                 return b2i(fc.eq())
1104         case OpARM64NotEqual:
1105                 return b2i(fc.ne())
1106         case OpARM64LessThan:
1107                 return b2i(fc.lt())
1108         case OpARM64LessThanU:
1109                 return b2i(fc.ult())
1110         case OpARM64GreaterThan:
1111                 return b2i(fc.gt())
1112         case OpARM64GreaterThanU:
1113                 return b2i(fc.ugt())
1114         case OpARM64LessEqual:
1115                 return b2i(fc.le())
1116         case OpARM64LessEqualU:
1117                 return b2i(fc.ule())
1118         case OpARM64GreaterEqual:
1119                 return b2i(fc.ge())
1120         case OpARM64GreaterEqualU:
1121                 return b2i(fc.uge())
1122         }
1123         return 0
1124 }
1125
1126 // logRule logs the use of the rule s. This will only be enabled if
1127 // rewrite rules were generated with the -log option, see gen/rulegen.go.
1128 func logRule(s string) {
1129         if ruleFile == nil {
1130                 // Open a log file to write log to. We open in append
1131                 // mode because all.bash runs the compiler lots of times,
1132                 // and we want the concatenation of all of those logs.
1133                 // This means, of course, that users need to rm the old log
1134                 // to get fresh data.
1135                 // TODO: all.bash runs compilers in parallel. Need to synchronize logging somehow?
1136                 w, err := os.OpenFile(filepath.Join(os.Getenv("GOROOT"), "src", "rulelog"),
1137                         os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
1138                 if err != nil {
1139                         panic(err)
1140                 }
1141                 ruleFile = w
1142         }
1143         _, err := fmt.Fprintln(ruleFile, s)
1144         if err != nil {
1145                 panic(err)
1146         }
1147 }
1148
1149 var ruleFile io.Writer
1150
1151 func min(x, y int64) int64 {
1152         if x < y {
1153                 return x
1154         }
1155         return y
1156 }
1157
1158 func isConstZero(v *Value) bool {
1159         switch v.Op {
1160         case OpConstNil:
1161                 return true
1162         case OpConst64, OpConst32, OpConst16, OpConst8, OpConstBool, OpConst32F, OpConst64F:
1163                 return v.AuxInt == 0
1164         }
1165         return false
1166 }
1167
1168 // reciprocalExact64 reports whether 1/c is exactly representable.
1169 func reciprocalExact64(c float64) bool {
1170         b := math.Float64bits(c)
1171         man := b & (1<<52 - 1)
1172         if man != 0 {
1173                 return false // not a power of 2, denormal, or NaN
1174         }
1175         exp := b >> 52 & (1<<11 - 1)
1176         // exponent bias is 0x3ff.  So taking the reciprocal of a number
1177         // changes the exponent to 0x7fe-exp.
1178         switch exp {
1179         case 0:
1180                 return false // Â±0
1181         case 0x7ff:
1182                 return false // Â±inf
1183         case 0x7fe:
1184                 return false // exponent is not representable
1185         default:
1186                 return true
1187         }
1188 }
1189
1190 // reciprocalExact32 reports whether 1/c is exactly representable.
1191 func reciprocalExact32(c float32) bool {
1192         b := math.Float32bits(c)
1193         man := b & (1<<23 - 1)
1194         if man != 0 {
1195                 return false // not a power of 2, denormal, or NaN
1196         }
1197         exp := b >> 23 & (1<<8 - 1)
1198         // exponent bias is 0x7f.  So taking the reciprocal of a number
1199         // changes the exponent to 0xfe-exp.
1200         switch exp {
1201         case 0:
1202                 return false // Â±0
1203         case 0xff:
1204                 return false // Â±inf
1205         case 0xfe:
1206                 return false // exponent is not representable
1207         default:
1208                 return true
1209         }
1210 }
1211
1212 // check if an immediate can be directly encoded into an ARM's instruction
1213 func isARMImmRot(v uint32) bool {
1214         for i := 0; i < 16; i++ {
1215                 if v&^0xff == 0 {
1216                         return true
1217                 }
1218                 v = v<<2 | v>>30
1219         }
1220
1221         return false
1222 }
1223
1224 // overlap reports whether the ranges given by the given offset and
1225 // size pairs overlap.
1226 func overlap(offset1, size1, offset2, size2 int64) bool {
1227         if offset1 >= offset2 && offset2+size2 > offset1 {
1228                 return true
1229         }
1230         if offset2 >= offset1 && offset1+size1 > offset2 {
1231                 return true
1232         }
1233         return false
1234 }
1235
1236 func areAdjacentOffsets(off1, off2, size int64) bool {
1237         return off1+size == off2 || off1 == off2+size
1238 }
1239
1240 // check if value zeroes out upper 32-bit of 64-bit register.
1241 // depth limits recursion depth. In AMD64.rules 3 is used as limit,
1242 // because it catches same amount of cases as 4.
1243 func zeroUpper32Bits(x *Value, depth int) bool {
1244         switch x.Op {
1245         case OpAMD64MOVLconst, OpAMD64MOVLload, OpAMD64MOVLQZX, OpAMD64MOVLloadidx1,
1246                 OpAMD64MOVWload, OpAMD64MOVWloadidx1, OpAMD64MOVBload, OpAMD64MOVBloadidx1,
1247                 OpAMD64MOVLloadidx4, OpAMD64ADDLload, OpAMD64SUBLload, OpAMD64ANDLload,
1248                 OpAMD64ORLload, OpAMD64XORLload, OpAMD64CVTTSD2SL,
1249                 OpAMD64ADDL, OpAMD64ADDLconst, OpAMD64SUBL, OpAMD64SUBLconst,
1250                 OpAMD64ANDL, OpAMD64ANDLconst, OpAMD64ORL, OpAMD64ORLconst,
1251                 OpAMD64XORL, OpAMD64XORLconst, OpAMD64NEGL, OpAMD64NOTL,
1252                 OpAMD64SHRL, OpAMD64SHRLconst, OpAMD64SARL, OpAMD64SARLconst,
1253                 OpAMD64SHLL, OpAMD64SHLLconst:
1254                 return true
1255         case OpArg:
1256                 return x.Type.Width == 4
1257         case OpPhi, OpSelect0, OpSelect1:
1258                 // Phis can use each-other as an arguments, instead of tracking visited values,
1259                 // just limit recursion depth.
1260                 if depth <= 0 {
1261                         return false
1262                 }
1263                 for i := range x.Args {
1264                         if !zeroUpper32Bits(x.Args[i], depth-1) {
1265                                 return false
1266                         }
1267                 }
1268                 return true
1269
1270         }
1271         return false
1272 }
1273
1274 // zeroUpper48Bits is similar to zeroUpper32Bits, but for upper 48 bits
1275 func zeroUpper48Bits(x *Value, depth int) bool {
1276         switch x.Op {
1277         case OpAMD64MOVWQZX, OpAMD64MOVWload, OpAMD64MOVWloadidx1, OpAMD64MOVWloadidx2:
1278                 return true
1279         case OpArg:
1280                 return x.Type.Width == 2
1281         case OpPhi, OpSelect0, OpSelect1:
1282                 // Phis can use each-other as an arguments, instead of tracking visited values,
1283                 // just limit recursion depth.
1284                 if depth <= 0 {
1285                         return false
1286                 }
1287                 for i := range x.Args {
1288                         if !zeroUpper48Bits(x.Args[i], depth-1) {
1289                                 return false
1290                         }
1291                 }
1292                 return true
1293
1294         }
1295         return false
1296 }
1297
1298 // zeroUpper56Bits is similar to zeroUpper32Bits, but for upper 56 bits
1299 func zeroUpper56Bits(x *Value, depth int) bool {
1300         switch x.Op {
1301         case OpAMD64MOVBQZX, OpAMD64MOVBload, OpAMD64MOVBloadidx1:
1302                 return true
1303         case OpArg:
1304                 return x.Type.Width == 1
1305         case OpPhi, OpSelect0, OpSelect1:
1306                 // Phis can use each-other as an arguments, instead of tracking visited values,
1307                 // just limit recursion depth.
1308                 if depth <= 0 {
1309                         return false
1310                 }
1311                 for i := range x.Args {
1312                         if !zeroUpper56Bits(x.Args[i], depth-1) {
1313                                 return false
1314                         }
1315                 }
1316                 return true
1317
1318         }
1319         return false
1320 }
1321
1322 // isInlinableMemmove reports whether the given arch performs a Move of the given size
1323 // faster than memmove. It will only return true if replacing the memmove with a Move is
1324 // safe, either because Move is small or because the arguments are disjoint.
1325 // This is used as a check for replacing memmove with Move ops.
1326 func isInlinableMemmove(dst, src *Value, sz int64, c *Config) bool {
1327         // It is always safe to convert memmove into Move when its arguments are disjoint.
1328         // Move ops may or may not be faster for large sizes depending on how the platform
1329         // lowers them, so we only perform this optimization on platforms that we know to
1330         // have fast Move ops.
1331         switch c.arch {
1332         case "amd64":
1333                 return sz <= 16 || (sz < 1024 && disjoint(dst, sz, src, sz))
1334         case "386", "arm64":
1335                 return sz <= 8
1336         case "s390x", "ppc64", "ppc64le":
1337                 return sz <= 8 || disjoint(dst, sz, src, sz)
1338         case "arm", "mips", "mips64", "mipsle", "mips64le":
1339                 return sz <= 4
1340         }
1341         return false
1342 }
1343
1344 // logLargeCopy logs the occurrence of a large copy.
1345 // The best place to do this is in the rewrite rules where the size of the move is easy to find.
1346 // "Large" is arbitrarily chosen to be 128 bytes; this may change.
1347 func logLargeCopy(v *Value, s int64) bool {
1348         if s < 128 {
1349                 return true
1350         }
1351         if logopt.Enabled() {
1352                 logopt.LogOpt(v.Pos, "copy", "lower", v.Block.Func.Name, fmt.Sprintf("%d bytes", s))
1353         }
1354         return true
1355 }
1356
1357 // hasSmallRotate reports whether the architecture has rotate instructions
1358 // for sizes < 32-bit.  This is used to decide whether to promote some rotations.
1359 func hasSmallRotate(c *Config) bool {
1360         switch c.arch {
1361         case "amd64", "386":
1362                 return true
1363         default:
1364                 return false
1365         }
1366 }
1367
1368 func newPPC64ShiftAuxInt(sh, mb, me, sz int64) int32 {
1369         if sh < 0 || sh >= sz {
1370                 panic("PPC64 shift arg sh out of range")
1371         }
1372         if mb < 0 || mb >= sz {
1373                 panic("PPC64 shift arg mb out of range")
1374         }
1375         if me < 0 || me >= sz {
1376                 panic("PPC64 shift arg me out of range")
1377         }
1378         return int32(sh<<16 | mb<<8 | me)
1379 }
1380
1381 func GetPPC64Shiftsh(auxint int64) int64 {
1382         return int64(int8(auxint >> 16))
1383 }
1384
1385 func GetPPC64Shiftmb(auxint int64) int64 {
1386         return int64(int8(auxint >> 8))
1387 }
1388
1389 func GetPPC64Shiftme(auxint int64) int64 {
1390         return int64(int8(auxint))
1391 }
1392
1393 // Test if this value can encoded as a mask for a rlwinm like
1394 // operation.  Masks can also extend from the msb and wrap to
1395 // the lsb too.  That is, the valid masks are 32 bit strings
1396 // of the form: 0..01..10..0 or 1..10..01..1 or 1...1
1397 func isPPC64WordRotateMask(v64 int64) bool {
1398         // Isolate rightmost 1 (if none 0) and add.
1399         v := uint32(v64)
1400         vp := (v & -v) + v
1401         // Likewise, for the wrapping case.
1402         vn := ^v
1403         vpn := (vn & -vn) + vn
1404         return (v&vp == 0 || vn&vpn == 0) && v != 0
1405 }
1406
1407 // Compress mask and shift into single value of the form
1408 // me | mb<<8 | rotate<<16 | nbits<<24 where me and mb can
1409 // be used to regenerate the input mask.
1410 func encodePPC64RotateMask(rotate, mask, nbits int64) int64 {
1411         var mb, me, mbn, men int
1412
1413         // Determine boundaries and then decode them
1414         if mask == 0 || ^mask == 0 || rotate >= nbits {
1415                 panic("Invalid PPC64 rotate mask")
1416         } else if nbits == 32 {
1417                 mb = bits.LeadingZeros32(uint32(mask))
1418                 me = 32 - bits.TrailingZeros32(uint32(mask))
1419                 mbn = bits.LeadingZeros32(^uint32(mask))
1420                 men = 32 - bits.TrailingZeros32(^uint32(mask))
1421         } else {
1422                 mb = bits.LeadingZeros64(uint64(mask))
1423                 me = 64 - bits.TrailingZeros64(uint64(mask))
1424                 mbn = bits.LeadingZeros64(^uint64(mask))
1425                 men = 64 - bits.TrailingZeros64(^uint64(mask))
1426         }
1427         // Check for a wrapping mask (e.g bits at 0 and 63)
1428         if mb == 0 && me == int(nbits) {
1429                 // swap the inverted values
1430                 mb, me = men, mbn
1431         }
1432
1433         return int64(me) | int64(mb<<8) | int64(rotate<<16) | int64(nbits<<24)
1434 }
1435
1436 // The inverse operation of encodePPC64RotateMask.  The values returned as
1437 // mb and me satisfy the POWER ISA definition of MASK(x,y) where MASK(mb,me) = mask.
1438 func DecodePPC64RotateMask(sauxint int64) (rotate, mb, me int64, mask uint64) {
1439         auxint := uint64(sauxint)
1440         rotate = int64((auxint >> 16) & 0xFF)
1441         mb = int64((auxint >> 8) & 0xFF)
1442         me = int64((auxint >> 0) & 0xFF)
1443         nbits := int64((auxint >> 24) & 0xFF)
1444         mask = ((1 << uint(nbits-mb)) - 1) ^ ((1 << uint(nbits-me)) - 1)
1445         if mb > me {
1446                 mask = ^mask
1447         }
1448         if nbits == 32 {
1449                 mask = uint64(uint32(mask))
1450         }
1451
1452         // Fixup ME to match ISA definition.  The second argument to MASK(..,me)
1453         // is inclusive.
1454         me = (me - 1) & (nbits - 1)
1455         return
1456 }
1457
1458 // This verifies that the mask is a set of
1459 // consecutive bits including the least
1460 // significant bit.
1461 func isPPC64ValidShiftMask(v int64) bool {
1462         if (v != 0) && ((v+1)&v) == 0 {
1463                 return true
1464         }
1465         return false
1466 }
1467
1468 func getPPC64ShiftMaskLength(v int64) int64 {
1469         return int64(bits.Len64(uint64(v)))
1470 }
1471
1472 // Decompose a shift right into an equivalent rotate/mask,
1473 // and return mask & m.
1474 func mergePPC64RShiftMask(m, s, nbits int64) int64 {
1475         smask := uint64((1<<uint(nbits))-1) >> uint(s)
1476         return m & int64(smask)
1477 }
1478
1479 // Combine (ANDconst [m] (SRWconst [s])) into (RLWINM [y]) or return 0
1480 func mergePPC64AndSrwi(m, s int64) int64 {
1481         mask := mergePPC64RShiftMask(m, s, 32)
1482         if !isPPC64WordRotateMask(mask) {
1483                 return 0
1484         }
1485         return encodePPC64RotateMask((32-s)&31, mask, 32)
1486 }
1487
1488 // Test if a shift right feeding into a CLRLSLDI can be merged into RLWINM.
1489 // Return the encoded RLWINM constant, or 0 if they cannot be merged.
1490 func mergePPC64ClrlsldiSrw(sld, srw int64) int64 {
1491         mask_1 := uint64(0xFFFFFFFF >> uint(srw))
1492         // for CLRLSLDI, it's more convient to think of it as a mask left bits then rotate left.
1493         mask_2 := uint64(0xFFFFFFFFFFFFFFFF) >> uint(GetPPC64Shiftmb(int64(sld)))
1494
1495         // Rewrite mask to apply after the final left shift.
1496         mask_3 := (mask_1 & mask_2) << uint(GetPPC64Shiftsh(sld))
1497
1498         r_1 := 32 - srw
1499         r_2 := GetPPC64Shiftsh(sld)
1500         r_3 := (r_1 + r_2) & 31 // This can wrap.
1501
1502         if uint64(uint32(mask_3)) != mask_3 || mask_3 == 0 {
1503                 return 0
1504         }
1505         return encodePPC64RotateMask(int64(r_3), int64(mask_3), 32)
1506 }
1507
1508 // Test if a RLWINM feeding into a CLRLSLDI can be merged into RLWINM.  Return
1509 // the encoded RLWINM constant, or 0 if they cannot be merged.
1510 func mergePPC64ClrlsldiRlwinm(sld int32, rlw int64) int64 {
1511         r_1, _, _, mask_1 := DecodePPC64RotateMask(rlw)
1512         // for CLRLSLDI, it's more convient to think of it as a mask left bits then rotate left.
1513         mask_2 := uint64(0xFFFFFFFFFFFFFFFF) >> uint(GetPPC64Shiftmb(int64(sld)))
1514
1515         // combine the masks, and adjust for the final left shift.
1516         mask_3 := (mask_1 & mask_2) << uint(GetPPC64Shiftsh(int64(sld)))
1517         r_2 := GetPPC64Shiftsh(int64(sld))
1518         r_3 := (r_1 + r_2) & 31 // This can wrap.
1519
1520         // Verify the result is still a valid bitmask of <= 32 bits.
1521         if !isPPC64WordRotateMask(int64(mask_3)) || uint64(uint32(mask_3)) != mask_3 {
1522                 return 0
1523         }
1524         return encodePPC64RotateMask(r_3, int64(mask_3), 32)
1525 }
1526
1527 // Compute the encoded RLWINM constant from combining (SLDconst [sld] (SRWconst [srw] x)),
1528 // or return 0 if they cannot be combined.
1529 func mergePPC64SldiSrw(sld, srw int64) int64 {
1530         if sld > srw || srw >= 32 {
1531                 return 0
1532         }
1533         mask_r := uint32(0xFFFFFFFF) >> uint(srw)
1534         mask_l := uint32(0xFFFFFFFF) >> uint(sld)
1535         mask := (mask_r & mask_l) << uint(sld)
1536         return encodePPC64RotateMask((32-srw+sld)&31, int64(mask), 32)
1537 }
1538
1539 // Convenience function to rotate a 32 bit constant value by another constant.
1540 func rotateLeft32(v, rotate int64) int64 {
1541         return int64(bits.RotateLeft32(uint32(v), int(rotate)))
1542 }
1543
1544 // encodes the lsb and width for arm(64) bitfield ops into the expected auxInt format.
1545 func armBFAuxInt(lsb, width int64) arm64BitField {
1546         if lsb < 0 || lsb > 63 {
1547                 panic("ARM(64) bit field lsb constant out of range")
1548         }
1549         if width < 1 || width > 64 {
1550                 panic("ARM(64) bit field width constant out of range")
1551         }
1552         return arm64BitField(width | lsb<<8)
1553 }
1554
1555 // returns the lsb part of the auxInt field of arm64 bitfield ops.
1556 func (bfc arm64BitField) getARM64BFlsb() int64 {
1557         return int64(uint64(bfc) >> 8)
1558 }
1559
1560 // returns the width part of the auxInt field of arm64 bitfield ops.
1561 func (bfc arm64BitField) getARM64BFwidth() int64 {
1562         return int64(bfc) & 0xff
1563 }
1564
1565 // checks if mask >> rshift applied at lsb is a valid arm64 bitfield op mask.
1566 func isARM64BFMask(lsb, mask, rshift int64) bool {
1567         shiftedMask := int64(uint64(mask) >> uint64(rshift))
1568         return shiftedMask != 0 && isPowerOfTwo64(shiftedMask+1) && nto(shiftedMask)+lsb < 64
1569 }
1570
1571 // returns the bitfield width of mask >> rshift for arm64 bitfield ops
1572 func arm64BFWidth(mask, rshift int64) int64 {
1573         shiftedMask := int64(uint64(mask) >> uint64(rshift))
1574         if shiftedMask == 0 {
1575                 panic("ARM64 BF mask is zero")
1576         }
1577         return nto(shiftedMask)
1578 }
1579
1580 // sizeof returns the size of t in bytes.
1581 // It will panic if t is not a *types.Type.
1582 func sizeof(t interface{}) int64 {
1583         return t.(*types.Type).Size()
1584 }
1585
1586 // registerizable reports whether t is a primitive type that fits in
1587 // a register. It assumes float64 values will always fit into registers
1588 // even if that isn't strictly true.
1589 func registerizable(b *Block, typ *types.Type) bool {
1590         if typ.IsPtrShaped() || typ.IsFloat() {
1591                 return true
1592         }
1593         if typ.IsInteger() {
1594                 return typ.Size() <= b.Func.Config.RegSize
1595         }
1596         return false
1597 }
1598
1599 // needRaceCleanup reports whether this call to racefuncenter/exit isn't needed.
1600 func needRaceCleanup(sym *AuxCall, v *Value) bool {
1601         f := v.Block.Func
1602         if !f.Config.Race {
1603                 return false
1604         }
1605         if !isSameCall(sym, "runtime.racefuncenter") && !isSameCall(sym, "runtime.racefuncexit") {
1606                 return false
1607         }
1608         for _, b := range f.Blocks {
1609                 for _, v := range b.Values {
1610                         switch v.Op {
1611                         case OpStaticCall, OpStaticLECall:
1612                                 // Check for racefuncenter will encounter racefuncexit and vice versa.
1613                                 // Allow calls to panic*
1614                                 s := v.Aux.(*AuxCall).Fn.String()
1615                                 switch s {
1616                                 case "runtime.racefuncenter", "runtime.racefuncexit",
1617                                         "runtime.panicdivide", "runtime.panicwrap",
1618                                         "runtime.panicshift":
1619                                         continue
1620                                 }
1621                                 // If we encountered any call, we need to keep racefunc*,
1622                                 // for accurate stacktraces.
1623                                 return false
1624                         case OpPanicBounds, OpPanicExtend:
1625                                 // Note: these are panic generators that are ok (like the static calls above).
1626                         case OpClosureCall, OpInterCall, OpClosureLECall, OpInterLECall:
1627                                 // We must keep the race functions if there are any other call types.
1628                                 return false
1629                         }
1630                 }
1631         }
1632         if isSameCall(sym, "runtime.racefuncenter") {
1633                 // TODO REGISTER ABI this needs to be cleaned up.
1634                 // If we're removing racefuncenter, remove its argument as well.
1635                 if v.Args[0].Op != OpStore {
1636                         if v.Op == OpStaticLECall {
1637                                 // there is no store, yet.
1638                                 return true
1639                         }
1640                         return false
1641                 }
1642                 mem := v.Args[0].Args[2]
1643                 v.Args[0].reset(OpCopy)
1644                 v.Args[0].AddArg(mem)
1645         }
1646         return true
1647 }
1648
1649 // symIsRO reports whether sym is a read-only global.
1650 func symIsRO(sym interface{}) bool {
1651         lsym := sym.(*obj.LSym)
1652         return lsym.Type == objabi.SRODATA && len(lsym.R) == 0
1653 }
1654
1655 // symIsROZero reports whether sym is a read-only global whose data contains all zeros.
1656 func symIsROZero(sym Sym) bool {
1657         lsym := sym.(*obj.LSym)
1658         if lsym.Type != objabi.SRODATA || len(lsym.R) != 0 {
1659                 return false
1660         }
1661         for _, b := range lsym.P {
1662                 if b != 0 {
1663                         return false
1664                 }
1665         }
1666         return true
1667 }
1668
1669 // read8 reads one byte from the read-only global sym at offset off.
1670 func read8(sym interface{}, off int64) uint8 {
1671         lsym := sym.(*obj.LSym)
1672         if off >= int64(len(lsym.P)) || off < 0 {
1673                 // Invalid index into the global sym.
1674                 // This can happen in dead code, so we don't want to panic.
1675                 // Just return any value, it will eventually get ignored.
1676                 // See issue 29215.
1677                 return 0
1678         }
1679         return lsym.P[off]
1680 }
1681
1682 // read16 reads two bytes from the read-only global sym at offset off.
1683 func read16(sym interface{}, off int64, byteorder binary.ByteOrder) uint16 {
1684         lsym := sym.(*obj.LSym)
1685         // lsym.P is written lazily.
1686         // Bytes requested after the end of lsym.P are 0.
1687         var src []byte
1688         if 0 <= off && off < int64(len(lsym.P)) {
1689                 src = lsym.P[off:]
1690         }
1691         buf := make([]byte, 2)
1692         copy(buf, src)
1693         return byteorder.Uint16(buf)
1694 }
1695
1696 // read32 reads four bytes from the read-only global sym at offset off.
1697 func read32(sym interface{}, off int64, byteorder binary.ByteOrder) uint32 {
1698         lsym := sym.(*obj.LSym)
1699         var src []byte
1700         if 0 <= off && off < int64(len(lsym.P)) {
1701                 src = lsym.P[off:]
1702         }
1703         buf := make([]byte, 4)
1704         copy(buf, src)
1705         return byteorder.Uint32(buf)
1706 }
1707
1708 // read64 reads eight bytes from the read-only global sym at offset off.
1709 func read64(sym interface{}, off int64, byteorder binary.ByteOrder) uint64 {
1710         lsym := sym.(*obj.LSym)
1711         var src []byte
1712         if 0 <= off && off < int64(len(lsym.P)) {
1713                 src = lsym.P[off:]
1714         }
1715         buf := make([]byte, 8)
1716         copy(buf, src)
1717         return byteorder.Uint64(buf)
1718 }
1719
1720 // sequentialAddresses reports true if it can prove that x + n == y
1721 func sequentialAddresses(x, y *Value, n int64) bool {
1722         if x.Op == Op386ADDL && y.Op == Op386LEAL1 && y.AuxInt == n && y.Aux == nil &&
1723                 (x.Args[0] == y.Args[0] && x.Args[1] == y.Args[1] ||
1724                         x.Args[0] == y.Args[1] && x.Args[1] == y.Args[0]) {
1725                 return true
1726         }
1727         if x.Op == Op386LEAL1 && y.Op == Op386LEAL1 && y.AuxInt == x.AuxInt+n && x.Aux == y.Aux &&
1728                 (x.Args[0] == y.Args[0] && x.Args[1] == y.Args[1] ||
1729                         x.Args[0] == y.Args[1] && x.Args[1] == y.Args[0]) {
1730                 return true
1731         }
1732         if x.Op == OpAMD64ADDQ && y.Op == OpAMD64LEAQ1 && y.AuxInt == n && y.Aux == nil &&
1733                 (x.Args[0] == y.Args[0] && x.Args[1] == y.Args[1] ||
1734                         x.Args[0] == y.Args[1] && x.Args[1] == y.Args[0]) {
1735                 return true
1736         }
1737         if x.Op == OpAMD64LEAQ1 && y.Op == OpAMD64LEAQ1 && y.AuxInt == x.AuxInt+n && x.Aux == y.Aux &&
1738                 (x.Args[0] == y.Args[0] && x.Args[1] == y.Args[1] ||
1739                         x.Args[0] == y.Args[1] && x.Args[1] == y.Args[0]) {
1740                 return true
1741         }
1742         return false
1743 }
1744
1745 // flagConstant represents the result of a compile-time comparison.
1746 // The sense of these flags does not necessarily represent the hardware's notion
1747 // of a flags register - these are just a compile-time construct.
1748 // We happen to match the semantics to those of arm/arm64.
1749 // Note that these semantics differ from x86: the carry flag has the opposite
1750 // sense on a subtraction!
1751 //   On amd64, C=1 represents a borrow, e.g. SBB on amd64 does x - y - C.
1752 //   On arm64, C=0 represents a borrow, e.g. SBC on arm64 does x - y - ^C.
1753 //    (because it does x + ^y + C).
1754 // See https://en.wikipedia.org/wiki/Carry_flag#Vs._borrow_flag
1755 type flagConstant uint8
1756
1757 // N reports whether the result of an operation is negative (high bit set).
1758 func (fc flagConstant) N() bool {
1759         return fc&1 != 0
1760 }
1761
1762 // Z reports whether the result of an operation is 0.
1763 func (fc flagConstant) Z() bool {
1764         return fc&2 != 0
1765 }
1766
1767 // C reports whether an unsigned add overflowed (carry), or an
1768 // unsigned subtract did not underflow (borrow).
1769 func (fc flagConstant) C() bool {
1770         return fc&4 != 0
1771 }
1772
1773 // V reports whether a signed operation overflowed or underflowed.
1774 func (fc flagConstant) V() bool {
1775         return fc&8 != 0
1776 }
1777
1778 func (fc flagConstant) eq() bool {
1779         return fc.Z()
1780 }
1781 func (fc flagConstant) ne() bool {
1782         return !fc.Z()
1783 }
1784 func (fc flagConstant) lt() bool {
1785         return fc.N() != fc.V()
1786 }
1787 func (fc flagConstant) le() bool {
1788         return fc.Z() || fc.lt()
1789 }
1790 func (fc flagConstant) gt() bool {
1791         return !fc.Z() && fc.ge()
1792 }
1793 func (fc flagConstant) ge() bool {
1794         return fc.N() == fc.V()
1795 }
1796 func (fc flagConstant) ult() bool {
1797         return !fc.C()
1798 }
1799 func (fc flagConstant) ule() bool {
1800         return fc.Z() || fc.ult()
1801 }
1802 func (fc flagConstant) ugt() bool {
1803         return !fc.Z() && fc.uge()
1804 }
1805 func (fc flagConstant) uge() bool {
1806         return fc.C()
1807 }
1808
1809 func (fc flagConstant) ltNoov() bool {
1810         return fc.lt() && !fc.V()
1811 }
1812 func (fc flagConstant) leNoov() bool {
1813         return fc.le() && !fc.V()
1814 }
1815 func (fc flagConstant) gtNoov() bool {
1816         return fc.gt() && !fc.V()
1817 }
1818 func (fc flagConstant) geNoov() bool {
1819         return fc.ge() && !fc.V()
1820 }
1821
1822 func (fc flagConstant) String() string {
1823         return fmt.Sprintf("N=%v,Z=%v,C=%v,V=%v", fc.N(), fc.Z(), fc.C(), fc.V())
1824 }
1825
1826 type flagConstantBuilder struct {
1827         N bool
1828         Z bool
1829         C bool
1830         V bool
1831 }
1832
1833 func (fcs flagConstantBuilder) encode() flagConstant {
1834         var fc flagConstant
1835         if fcs.N {
1836                 fc |= 1
1837         }
1838         if fcs.Z {
1839                 fc |= 2
1840         }
1841         if fcs.C {
1842                 fc |= 4
1843         }
1844         if fcs.V {
1845                 fc |= 8
1846         }
1847         return fc
1848 }
1849
1850 // Note: addFlags(x,y) != subFlags(x,-y) in some situations:
1851 //  - the results of the C flag are different
1852 //  - the results of the V flag when y==minint are different
1853
1854 // addFlags64 returns the flags that would be set from computing x+y.
1855 func addFlags64(x, y int64) flagConstant {
1856         var fcb flagConstantBuilder
1857         fcb.Z = x+y == 0
1858         fcb.N = x+y < 0
1859         fcb.C = uint64(x+y) < uint64(x)
1860         fcb.V = x >= 0 && y >= 0 && x+y < 0 || x < 0 && y < 0 && x+y >= 0
1861         return fcb.encode()
1862 }
1863
1864 // subFlags64 returns the flags that would be set from computing x-y.
1865 func subFlags64(x, y int64) flagConstant {
1866         var fcb flagConstantBuilder
1867         fcb.Z = x-y == 0
1868         fcb.N = x-y < 0
1869         fcb.C = uint64(y) <= uint64(x) // This code follows the arm carry flag model.
1870         fcb.V = x >= 0 && y < 0 && x-y < 0 || x < 0 && y >= 0 && x-y >= 0
1871         return fcb.encode()
1872 }
1873
1874 // addFlags32 returns the flags that would be set from computing x+y.
1875 func addFlags32(x, y int32) flagConstant {
1876         var fcb flagConstantBuilder
1877         fcb.Z = x+y == 0
1878         fcb.N = x+y < 0
1879         fcb.C = uint32(x+y) < uint32(x)
1880         fcb.V = x >= 0 && y >= 0 && x+y < 0 || x < 0 && y < 0 && x+y >= 0
1881         return fcb.encode()
1882 }
1883
1884 // subFlags32 returns the flags that would be set from computing x-y.
1885 func subFlags32(x, y int32) flagConstant {
1886         var fcb flagConstantBuilder
1887         fcb.Z = x-y == 0
1888         fcb.N = x-y < 0
1889         fcb.C = uint32(y) <= uint32(x) // This code follows the arm carry flag model.
1890         fcb.V = x >= 0 && y < 0 && x-y < 0 || x < 0 && y >= 0 && x-y >= 0
1891         return fcb.encode()
1892 }
1893
1894 // logicFlags64 returns flags set to the sign/zeroness of x.
1895 // C and V are set to false.
1896 func logicFlags64(x int64) flagConstant {
1897         var fcb flagConstantBuilder
1898         fcb.Z = x == 0
1899         fcb.N = x < 0
1900         return fcb.encode()
1901 }
1902
1903 // logicFlags32 returns flags set to the sign/zeroness of x.
1904 // C and V are set to false.
1905 func logicFlags32(x int32) flagConstant {
1906         var fcb flagConstantBuilder
1907         fcb.Z = x == 0
1908         fcb.N = x < 0
1909         return fcb.encode()
1910 }