]> Cypherpunks.ru repositories - gostls13.git/blob - src/cmd/compile/internal/ssa/rewrite.go
cmd/compile: plumb abi info into ssagen/ssa
[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 that 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 && 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 // de-virtualize an InterCall
749 // 'sym' is the symbol for the itab
750 func devirt(v *Value, aux Aux, sym Sym, offset int64) *AuxCall {
751         f := v.Block.Func
752         n, ok := sym.(*obj.LSym)
753         if !ok {
754                 return nil
755         }
756         lsym := f.fe.DerefItab(n, offset)
757         if f.pass.debug > 0 {
758                 if lsym != nil {
759                         f.Warnl(v.Pos, "de-virtualizing call")
760                 } else {
761                         f.Warnl(v.Pos, "couldn't de-virtualize call")
762                 }
763         }
764         if lsym == nil {
765                 return nil
766         }
767         va := aux.(*AuxCall)
768         return StaticAuxCall(lsym, va.args, va.results, va.abiInfo)
769 }
770
771 // de-virtualize an InterLECall
772 // 'sym' is the symbol for the itab
773 func devirtLESym(v *Value, aux Aux, sym Sym, offset int64) *obj.LSym {
774         n, ok := sym.(*obj.LSym)
775         if !ok {
776                 return nil
777         }
778
779         f := v.Block.Func
780         lsym := f.fe.DerefItab(n, offset)
781         if f.pass.debug > 0 {
782                 if lsym != nil {
783                         f.Warnl(v.Pos, "de-virtualizing call")
784                 } else {
785                         f.Warnl(v.Pos, "couldn't de-virtualize call")
786                 }
787         }
788         if lsym == nil {
789                 return nil
790         }
791         return lsym
792 }
793
794 func devirtLECall(v *Value, sym *obj.LSym) *Value {
795         v.Op = OpStaticLECall
796         v.Aux.(*AuxCall).Fn = sym
797         v.RemoveArg(0)
798         return v
799 }
800
801 // isSamePtr reports whether p1 and p2 point to the same address.
802 func isSamePtr(p1, p2 *Value) bool {
803         if p1 == p2 {
804                 return true
805         }
806         if p1.Op != p2.Op {
807                 return false
808         }
809         switch p1.Op {
810         case OpOffPtr:
811                 return p1.AuxInt == p2.AuxInt && isSamePtr(p1.Args[0], p2.Args[0])
812         case OpAddr, OpLocalAddr:
813                 // OpAddr's 0th arg is either OpSP or OpSB, which means that it is uniquely identified by its Op.
814                 // Checking for value equality only works after [z]cse has run.
815                 return p1.Aux == p2.Aux && p1.Args[0].Op == p2.Args[0].Op
816         case OpAddPtr:
817                 return p1.Args[1] == p2.Args[1] && isSamePtr(p1.Args[0], p2.Args[0])
818         }
819         return false
820 }
821
822 func isStackPtr(v *Value) bool {
823         for v.Op == OpOffPtr || v.Op == OpAddPtr {
824                 v = v.Args[0]
825         }
826         return v.Op == OpSP || v.Op == OpLocalAddr
827 }
828
829 // disjoint reports whether the memory region specified by [p1:p1+n1)
830 // does not overlap with [p2:p2+n2).
831 // A return value of false does not imply the regions overlap.
832 func disjoint(p1 *Value, n1 int64, p2 *Value, n2 int64) bool {
833         if n1 == 0 || n2 == 0 {
834                 return true
835         }
836         if p1 == p2 {
837                 return false
838         }
839         baseAndOffset := func(ptr *Value) (base *Value, offset int64) {
840                 base, offset = ptr, 0
841                 for base.Op == OpOffPtr {
842                         offset += base.AuxInt
843                         base = base.Args[0]
844                 }
845                 return base, offset
846         }
847         p1, off1 := baseAndOffset(p1)
848         p2, off2 := baseAndOffset(p2)
849         if isSamePtr(p1, p2) {
850                 return !overlap(off1, n1, off2, n2)
851         }
852         // p1 and p2 are not the same, so if they are both OpAddrs then
853         // they point to different variables.
854         // If one pointer is on the stack and the other is an argument
855         // then they can't overlap.
856         switch p1.Op {
857         case OpAddr, OpLocalAddr:
858                 if p2.Op == OpAddr || p2.Op == OpLocalAddr || p2.Op == OpSP {
859                         return true
860                 }
861                 return p2.Op == OpArg && p1.Args[0].Op == OpSP
862         case OpArg:
863                 if p2.Op == OpSP || p2.Op == OpLocalAddr {
864                         return true
865                 }
866         case OpSP:
867                 return p2.Op == OpAddr || p2.Op == OpLocalAddr || p2.Op == OpArg || p2.Op == OpSP
868         }
869         return false
870 }
871
872 // moveSize returns the number of bytes an aligned MOV instruction moves
873 func moveSize(align int64, c *Config) int64 {
874         switch {
875         case align%8 == 0 && c.PtrSize == 8:
876                 return 8
877         case align%4 == 0:
878                 return 4
879         case align%2 == 0:
880                 return 2
881         }
882         return 1
883 }
884
885 // mergePoint finds a block among a's blocks which dominates b and is itself
886 // dominated by all of a's blocks. Returns nil if it can't find one.
887 // Might return nil even if one does exist.
888 func mergePoint(b *Block, a ...*Value) *Block {
889         // Walk backward from b looking for one of the a's blocks.
890
891         // Max distance
892         d := 100
893
894         for d > 0 {
895                 for _, x := range a {
896                         if b == x.Block {
897                                 goto found
898                         }
899                 }
900                 if len(b.Preds) > 1 {
901                         // Don't know which way to go back. Abort.
902                         return nil
903                 }
904                 b = b.Preds[0].b
905                 d--
906         }
907         return nil // too far away
908 found:
909         // At this point, r is the first value in a that we find by walking backwards.
910         // if we return anything, r will be it.
911         r := b
912
913         // Keep going, counting the other a's that we find. They must all dominate r.
914         na := 0
915         for d > 0 {
916                 for _, x := range a {
917                         if b == x.Block {
918                                 na++
919                         }
920                 }
921                 if na == len(a) {
922                         // Found all of a in a backwards walk. We can return r.
923                         return r
924                 }
925                 if len(b.Preds) > 1 {
926                         return nil
927                 }
928                 b = b.Preds[0].b
929                 d--
930
931         }
932         return nil // too far away
933 }
934
935 // clobber invalidates values. Returns true.
936 // clobber is used by rewrite rules to:
937 //   A) make sure the values are really dead and never used again.
938 //   B) decrement use counts of the values' args.
939 func clobber(vv ...*Value) bool {
940         for _, v := range vv {
941                 v.reset(OpInvalid)
942                 // Note: leave v.Block intact.  The Block field is used after clobber.
943         }
944         return true
945 }
946
947 // clobberIfDead resets v when use count is 1. Returns true.
948 // clobberIfDead is used by rewrite rules to decrement
949 // use counts of v's args when v is dead and never used.
950 func clobberIfDead(v *Value) bool {
951         if v.Uses == 1 {
952                 v.reset(OpInvalid)
953         }
954         // Note: leave v.Block intact.  The Block field is used after clobberIfDead.
955         return true
956 }
957
958 // noteRule is an easy way to track if a rule is matched when writing
959 // new ones.  Make the rule of interest also conditional on
960 //     noteRule("note to self: rule of interest matched")
961 // and that message will print when the rule matches.
962 func noteRule(s string) bool {
963         fmt.Println(s)
964         return true
965 }
966
967 // countRule increments Func.ruleMatches[key].
968 // If Func.ruleMatches is non-nil at the end
969 // of compilation, it will be printed to stdout.
970 // This is intended to make it easier to find which functions
971 // which contain lots of rules matches when developing new rules.
972 func countRule(v *Value, key string) bool {
973         f := v.Block.Func
974         if f.ruleMatches == nil {
975                 f.ruleMatches = make(map[string]int)
976         }
977         f.ruleMatches[key]++
978         return true
979 }
980
981 // warnRule generates compiler debug output with string s when
982 // v is not in autogenerated code, cond is true and the rule has fired.
983 func warnRule(cond bool, v *Value, s string) bool {
984         if pos := v.Pos; pos.Line() > 1 && cond {
985                 v.Block.Func.Warnl(pos, s)
986         }
987         return true
988 }
989
990 // for a pseudo-op like (LessThan x), extract x
991 func flagArg(v *Value) *Value {
992         if len(v.Args) != 1 || !v.Args[0].Type.IsFlags() {
993                 return nil
994         }
995         return v.Args[0]
996 }
997
998 // arm64Negate finds the complement to an ARM64 condition code,
999 // for example !Equal -> NotEqual or !LessThan -> GreaterEqual
1000 //
1001 // For floating point, it's more subtle because NaN is unordered. We do
1002 // !LessThanF -> NotLessThanF, the latter takes care of NaNs.
1003 func arm64Negate(op Op) Op {
1004         switch op {
1005         case OpARM64LessThan:
1006                 return OpARM64GreaterEqual
1007         case OpARM64LessThanU:
1008                 return OpARM64GreaterEqualU
1009         case OpARM64GreaterThan:
1010                 return OpARM64LessEqual
1011         case OpARM64GreaterThanU:
1012                 return OpARM64LessEqualU
1013         case OpARM64LessEqual:
1014                 return OpARM64GreaterThan
1015         case OpARM64LessEqualU:
1016                 return OpARM64GreaterThanU
1017         case OpARM64GreaterEqual:
1018                 return OpARM64LessThan
1019         case OpARM64GreaterEqualU:
1020                 return OpARM64LessThanU
1021         case OpARM64Equal:
1022                 return OpARM64NotEqual
1023         case OpARM64NotEqual:
1024                 return OpARM64Equal
1025         case OpARM64LessThanF:
1026                 return OpARM64NotLessThanF
1027         case OpARM64NotLessThanF:
1028                 return OpARM64LessThanF
1029         case OpARM64LessEqualF:
1030                 return OpARM64NotLessEqualF
1031         case OpARM64NotLessEqualF:
1032                 return OpARM64LessEqualF
1033         case OpARM64GreaterThanF:
1034                 return OpARM64NotGreaterThanF
1035         case OpARM64NotGreaterThanF:
1036                 return OpARM64GreaterThanF
1037         case OpARM64GreaterEqualF:
1038                 return OpARM64NotGreaterEqualF
1039         case OpARM64NotGreaterEqualF:
1040                 return OpARM64GreaterEqualF
1041         default:
1042                 panic("unreachable")
1043         }
1044 }
1045
1046 // arm64Invert evaluates (InvertFlags op), which
1047 // is the same as altering the condition codes such
1048 // that the same result would be produced if the arguments
1049 // to the flag-generating instruction were reversed, e.g.
1050 // (InvertFlags (CMP x y)) -> (CMP y x)
1051 func arm64Invert(op Op) Op {
1052         switch op {
1053         case OpARM64LessThan:
1054                 return OpARM64GreaterThan
1055         case OpARM64LessThanU:
1056                 return OpARM64GreaterThanU
1057         case OpARM64GreaterThan:
1058                 return OpARM64LessThan
1059         case OpARM64GreaterThanU:
1060                 return OpARM64LessThanU
1061         case OpARM64LessEqual:
1062                 return OpARM64GreaterEqual
1063         case OpARM64LessEqualU:
1064                 return OpARM64GreaterEqualU
1065         case OpARM64GreaterEqual:
1066                 return OpARM64LessEqual
1067         case OpARM64GreaterEqualU:
1068                 return OpARM64LessEqualU
1069         case OpARM64Equal, OpARM64NotEqual:
1070                 return op
1071         case OpARM64LessThanF:
1072                 return OpARM64GreaterThanF
1073         case OpARM64GreaterThanF:
1074                 return OpARM64LessThanF
1075         case OpARM64LessEqualF:
1076                 return OpARM64GreaterEqualF
1077         case OpARM64GreaterEqualF:
1078                 return OpARM64LessEqualF
1079         case OpARM64NotLessThanF:
1080                 return OpARM64NotGreaterThanF
1081         case OpARM64NotGreaterThanF:
1082                 return OpARM64NotLessThanF
1083         case OpARM64NotLessEqualF:
1084                 return OpARM64NotGreaterEqualF
1085         case OpARM64NotGreaterEqualF:
1086                 return OpARM64NotLessEqualF
1087         default:
1088                 panic("unreachable")
1089         }
1090 }
1091
1092 // evaluate an ARM64 op against a flags value
1093 // that is potentially constant; return 1 for true,
1094 // -1 for false, and 0 for not constant.
1095 func ccARM64Eval(op Op, flags *Value) int {
1096         fop := flags.Op
1097         if fop == OpARM64InvertFlags {
1098                 return -ccARM64Eval(op, flags.Args[0])
1099         }
1100         if fop != OpARM64FlagConstant {
1101                 return 0
1102         }
1103         fc := flagConstant(flags.AuxInt)
1104         b2i := func(b bool) int {
1105                 if b {
1106                         return 1
1107                 }
1108                 return -1
1109         }
1110         switch op {
1111         case OpARM64Equal:
1112                 return b2i(fc.eq())
1113         case OpARM64NotEqual:
1114                 return b2i(fc.ne())
1115         case OpARM64LessThan:
1116                 return b2i(fc.lt())
1117         case OpARM64LessThanU:
1118                 return b2i(fc.ult())
1119         case OpARM64GreaterThan:
1120                 return b2i(fc.gt())
1121         case OpARM64GreaterThanU:
1122                 return b2i(fc.ugt())
1123         case OpARM64LessEqual:
1124                 return b2i(fc.le())
1125         case OpARM64LessEqualU:
1126                 return b2i(fc.ule())
1127         case OpARM64GreaterEqual:
1128                 return b2i(fc.ge())
1129         case OpARM64GreaterEqualU:
1130                 return b2i(fc.uge())
1131         }
1132         return 0
1133 }
1134
1135 // logRule logs the use of the rule s. This will only be enabled if
1136 // rewrite rules were generated with the -log option, see gen/rulegen.go.
1137 func logRule(s string) {
1138         if ruleFile == nil {
1139                 // Open a log file to write log to. We open in append
1140                 // mode because all.bash runs the compiler lots of times,
1141                 // and we want the concatenation of all of those logs.
1142                 // This means, of course, that users need to rm the old log
1143                 // to get fresh data.
1144                 // TODO: all.bash runs compilers in parallel. Need to synchronize logging somehow?
1145                 w, err := os.OpenFile(filepath.Join(os.Getenv("GOROOT"), "src", "rulelog"),
1146                         os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666)
1147                 if err != nil {
1148                         panic(err)
1149                 }
1150                 ruleFile = w
1151         }
1152         _, err := fmt.Fprintln(ruleFile, s)
1153         if err != nil {
1154                 panic(err)
1155         }
1156 }
1157
1158 var ruleFile io.Writer
1159
1160 func min(x, y int64) int64 {
1161         if x < y {
1162                 return x
1163         }
1164         return y
1165 }
1166
1167 func isConstZero(v *Value) bool {
1168         switch v.Op {
1169         case OpConstNil:
1170                 return true
1171         case OpConst64, OpConst32, OpConst16, OpConst8, OpConstBool, OpConst32F, OpConst64F:
1172                 return v.AuxInt == 0
1173         }
1174         return false
1175 }
1176
1177 // reciprocalExact64 reports whether 1/c is exactly representable.
1178 func reciprocalExact64(c float64) bool {
1179         b := math.Float64bits(c)
1180         man := b & (1<<52 - 1)
1181         if man != 0 {
1182                 return false // not a power of 2, denormal, or NaN
1183         }
1184         exp := b >> 52 & (1<<11 - 1)
1185         // exponent bias is 0x3ff.  So taking the reciprocal of a number
1186         // changes the exponent to 0x7fe-exp.
1187         switch exp {
1188         case 0:
1189                 return false // Â±0
1190         case 0x7ff:
1191                 return false // Â±inf
1192         case 0x7fe:
1193                 return false // exponent is not representable
1194         default:
1195                 return true
1196         }
1197 }
1198
1199 // reciprocalExact32 reports whether 1/c is exactly representable.
1200 func reciprocalExact32(c float32) bool {
1201         b := math.Float32bits(c)
1202         man := b & (1<<23 - 1)
1203         if man != 0 {
1204                 return false // not a power of 2, denormal, or NaN
1205         }
1206         exp := b >> 23 & (1<<8 - 1)
1207         // exponent bias is 0x7f.  So taking the reciprocal of a number
1208         // changes the exponent to 0xfe-exp.
1209         switch exp {
1210         case 0:
1211                 return false // Â±0
1212         case 0xff:
1213                 return false // Â±inf
1214         case 0xfe:
1215                 return false // exponent is not representable
1216         default:
1217                 return true
1218         }
1219 }
1220
1221 // check if an immediate can be directly encoded into an ARM's instruction
1222 func isARMImmRot(v uint32) bool {
1223         for i := 0; i < 16; i++ {
1224                 if v&^0xff == 0 {
1225                         return true
1226                 }
1227                 v = v<<2 | v>>30
1228         }
1229
1230         return false
1231 }
1232
1233 // overlap reports whether the ranges given by the given offset and
1234 // size pairs overlap.
1235 func overlap(offset1, size1, offset2, size2 int64) bool {
1236         if offset1 >= offset2 && offset2+size2 > offset1 {
1237                 return true
1238         }
1239         if offset2 >= offset1 && offset1+size1 > offset2 {
1240                 return true
1241         }
1242         return false
1243 }
1244
1245 func areAdjacentOffsets(off1, off2, size int64) bool {
1246         return off1+size == off2 || off1 == off2+size
1247 }
1248
1249 // check if value zeroes out upper 32-bit of 64-bit register.
1250 // depth limits recursion depth. In AMD64.rules 3 is used as limit,
1251 // because it catches same amount of cases as 4.
1252 func zeroUpper32Bits(x *Value, depth int) bool {
1253         switch x.Op {
1254         case OpAMD64MOVLconst, OpAMD64MOVLload, OpAMD64MOVLQZX, OpAMD64MOVLloadidx1,
1255                 OpAMD64MOVWload, OpAMD64MOVWloadidx1, OpAMD64MOVBload, OpAMD64MOVBloadidx1,
1256                 OpAMD64MOVLloadidx4, OpAMD64ADDLload, OpAMD64SUBLload, OpAMD64ANDLload,
1257                 OpAMD64ORLload, OpAMD64XORLload, OpAMD64CVTTSD2SL,
1258                 OpAMD64ADDL, OpAMD64ADDLconst, OpAMD64SUBL, OpAMD64SUBLconst,
1259                 OpAMD64ANDL, OpAMD64ANDLconst, OpAMD64ORL, OpAMD64ORLconst,
1260                 OpAMD64XORL, OpAMD64XORLconst, OpAMD64NEGL, OpAMD64NOTL,
1261                 OpAMD64SHRL, OpAMD64SHRLconst, OpAMD64SARL, OpAMD64SARLconst,
1262                 OpAMD64SHLL, OpAMD64SHLLconst:
1263                 return true
1264         case OpArg:
1265                 return x.Type.Width == 4
1266         case OpPhi, OpSelect0, OpSelect1:
1267                 // Phis can use each-other as an arguments, instead of tracking visited values,
1268                 // just limit recursion depth.
1269                 if depth <= 0 {
1270                         return false
1271                 }
1272                 for i := range x.Args {
1273                         if !zeroUpper32Bits(x.Args[i], depth-1) {
1274                                 return false
1275                         }
1276                 }
1277                 return true
1278
1279         }
1280         return false
1281 }
1282
1283 // zeroUpper48Bits is similar to zeroUpper32Bits, but for upper 48 bits
1284 func zeroUpper48Bits(x *Value, depth int) bool {
1285         switch x.Op {
1286         case OpAMD64MOVWQZX, OpAMD64MOVWload, OpAMD64MOVWloadidx1, OpAMD64MOVWloadidx2:
1287                 return true
1288         case OpArg:
1289                 return x.Type.Width == 2
1290         case OpPhi, OpSelect0, OpSelect1:
1291                 // Phis can use each-other as an arguments, instead of tracking visited values,
1292                 // just limit recursion depth.
1293                 if depth <= 0 {
1294                         return false
1295                 }
1296                 for i := range x.Args {
1297                         if !zeroUpper48Bits(x.Args[i], depth-1) {
1298                                 return false
1299                         }
1300                 }
1301                 return true
1302
1303         }
1304         return false
1305 }
1306
1307 // zeroUpper56Bits is similar to zeroUpper32Bits, but for upper 56 bits
1308 func zeroUpper56Bits(x *Value, depth int) bool {
1309         switch x.Op {
1310         case OpAMD64MOVBQZX, OpAMD64MOVBload, OpAMD64MOVBloadidx1:
1311                 return true
1312         case OpArg:
1313                 return x.Type.Width == 1
1314         case OpPhi, OpSelect0, OpSelect1:
1315                 // Phis can use each-other as an arguments, instead of tracking visited values,
1316                 // just limit recursion depth.
1317                 if depth <= 0 {
1318                         return false
1319                 }
1320                 for i := range x.Args {
1321                         if !zeroUpper56Bits(x.Args[i], depth-1) {
1322                                 return false
1323                         }
1324                 }
1325                 return true
1326
1327         }
1328         return false
1329 }
1330
1331 // isInlinableMemmove reports whether the given arch performs a Move of the given size
1332 // faster than memmove. It will only return true if replacing the memmove with a Move is
1333 // safe, either because Move is small or because the arguments are disjoint.
1334 // This is used as a check for replacing memmove with Move ops.
1335 func isInlinableMemmove(dst, src *Value, sz int64, c *Config) bool {
1336         // It is always safe to convert memmove into Move when its arguments are disjoint.
1337         // Move ops may or may not be faster for large sizes depending on how the platform
1338         // lowers them, so we only perform this optimization on platforms that we know to
1339         // have fast Move ops.
1340         switch c.arch {
1341         case "amd64":
1342                 return sz <= 16 || (sz < 1024 && disjoint(dst, sz, src, sz))
1343         case "386", "arm64":
1344                 return sz <= 8
1345         case "s390x", "ppc64", "ppc64le":
1346                 return sz <= 8 || disjoint(dst, sz, src, sz)
1347         case "arm", "mips", "mips64", "mipsle", "mips64le":
1348                 return sz <= 4
1349         }
1350         return false
1351 }
1352
1353 // logLargeCopy logs the occurrence of a large copy.
1354 // The best place to do this is in the rewrite rules where the size of the move is easy to find.
1355 // "Large" is arbitrarily chosen to be 128 bytes; this may change.
1356 func logLargeCopy(v *Value, s int64) bool {
1357         if s < 128 {
1358                 return true
1359         }
1360         if logopt.Enabled() {
1361                 logopt.LogOpt(v.Pos, "copy", "lower", v.Block.Func.Name, fmt.Sprintf("%d bytes", s))
1362         }
1363         return true
1364 }
1365
1366 // hasSmallRotate reports whether the architecture has rotate instructions
1367 // for sizes < 32-bit.  This is used to decide whether to promote some rotations.
1368 func hasSmallRotate(c *Config) bool {
1369         switch c.arch {
1370         case "amd64", "386":
1371                 return true
1372         default:
1373                 return false
1374         }
1375 }
1376
1377 func newPPC64ShiftAuxInt(sh, mb, me, sz int64) int32 {
1378         if sh < 0 || sh >= sz {
1379                 panic("PPC64 shift arg sh out of range")
1380         }
1381         if mb < 0 || mb >= sz {
1382                 panic("PPC64 shift arg mb out of range")
1383         }
1384         if me < 0 || me >= sz {
1385                 panic("PPC64 shift arg me out of range")
1386         }
1387         return int32(sh<<16 | mb<<8 | me)
1388 }
1389
1390 func GetPPC64Shiftsh(auxint int64) int64 {
1391         return int64(int8(auxint >> 16))
1392 }
1393
1394 func GetPPC64Shiftmb(auxint int64) int64 {
1395         return int64(int8(auxint >> 8))
1396 }
1397
1398 func GetPPC64Shiftme(auxint int64) int64 {
1399         return int64(int8(auxint))
1400 }
1401
1402 // Test if this value can encoded as a mask for a rlwinm like
1403 // operation.  Masks can also extend from the msb and wrap to
1404 // the lsb too.  That is, the valid masks are 32 bit strings
1405 // of the form: 0..01..10..0 or 1..10..01..1 or 1...1
1406 func isPPC64WordRotateMask(v64 int64) bool {
1407         // Isolate rightmost 1 (if none 0) and add.
1408         v := uint32(v64)
1409         vp := (v & -v) + v
1410         // Likewise, for the wrapping case.
1411         vn := ^v
1412         vpn := (vn & -vn) + vn
1413         return (v&vp == 0 || vn&vpn == 0) && v != 0
1414 }
1415
1416 // Compress mask and and shift into single value of the form
1417 // me | mb<<8 | rotate<<16 | nbits<<24 where me and mb can
1418 // be used to regenerate the input mask.
1419 func encodePPC64RotateMask(rotate, mask, nbits int64) int64 {
1420         var mb, me, mbn, men int
1421
1422         // Determine boundaries and then decode them
1423         if mask == 0 || ^mask == 0 || rotate >= nbits {
1424                 panic("Invalid PPC64 rotate mask")
1425         } else if nbits == 32 {
1426                 mb = bits.LeadingZeros32(uint32(mask))
1427                 me = 32 - bits.TrailingZeros32(uint32(mask))
1428                 mbn = bits.LeadingZeros32(^uint32(mask))
1429                 men = 32 - bits.TrailingZeros32(^uint32(mask))
1430         } else {
1431                 mb = bits.LeadingZeros64(uint64(mask))
1432                 me = 64 - bits.TrailingZeros64(uint64(mask))
1433                 mbn = bits.LeadingZeros64(^uint64(mask))
1434                 men = 64 - bits.TrailingZeros64(^uint64(mask))
1435         }
1436         // Check for a wrapping mask (e.g bits at 0 and 63)
1437         if mb == 0 && me == int(nbits) {
1438                 // swap the inverted values
1439                 mb, me = men, mbn
1440         }
1441
1442         return int64(me) | int64(mb<<8) | int64(rotate<<16) | int64(nbits<<24)
1443 }
1444
1445 // The inverse operation of encodePPC64RotateMask.  The values returned as
1446 // mb and me satisfy the POWER ISA definition of MASK(x,y) where MASK(mb,me) = mask.
1447 func DecodePPC64RotateMask(sauxint int64) (rotate, mb, me int64, mask uint64) {
1448         auxint := uint64(sauxint)
1449         rotate = int64((auxint >> 16) & 0xFF)
1450         mb = int64((auxint >> 8) & 0xFF)
1451         me = int64((auxint >> 0) & 0xFF)
1452         nbits := int64((auxint >> 24) & 0xFF)
1453         mask = ((1 << uint(nbits-mb)) - 1) ^ ((1 << uint(nbits-me)) - 1)
1454         if mb > me {
1455                 mask = ^mask
1456         }
1457         if nbits == 32 {
1458                 mask = uint64(uint32(mask))
1459         }
1460
1461         // Fixup ME to match ISA definition.  The second argument to MASK(..,me)
1462         // is inclusive.
1463         me = (me - 1) & (nbits - 1)
1464         return
1465 }
1466
1467 // This verifies that the mask is a set of
1468 // consecutive bits including the least
1469 // significant bit.
1470 func isPPC64ValidShiftMask(v int64) bool {
1471         if (v != 0) && ((v+1)&v) == 0 {
1472                 return true
1473         }
1474         return false
1475 }
1476
1477 func getPPC64ShiftMaskLength(v int64) int64 {
1478         return int64(bits.Len64(uint64(v)))
1479 }
1480
1481 // Decompose a shift right into an equivalent rotate/mask,
1482 // and return mask & m.
1483 func mergePPC64RShiftMask(m, s, nbits int64) int64 {
1484         smask := uint64((1<<uint(nbits))-1) >> uint(s)
1485         return m & int64(smask)
1486 }
1487
1488 // Combine (ANDconst [m] (SRWconst [s])) into (RLWINM [y]) or return 0
1489 func mergePPC64AndSrwi(m, s int64) int64 {
1490         mask := mergePPC64RShiftMask(m, s, 32)
1491         if !isPPC64WordRotateMask(mask) {
1492                 return 0
1493         }
1494         return encodePPC64RotateMask(32-s, mask, 32)
1495 }
1496
1497 // Test if a shift right feeding into a CLRLSLDI can be merged into RLWINM.
1498 // Return the encoded RLWINM constant, or 0 if they cannot be merged.
1499 func mergePPC64ClrlsldiSrw(sld, srw int64) int64 {
1500         mask_1 := uint64(0xFFFFFFFF >> uint(srw))
1501         // for CLRLSLDI, it's more convient to think of it as a mask left bits then rotate left.
1502         mask_2 := uint64(0xFFFFFFFFFFFFFFFF) >> uint(GetPPC64Shiftmb(int64(sld)))
1503
1504         // Rewrite mask to apply after the final left shift.
1505         mask_3 := (mask_1 & mask_2) << uint(GetPPC64Shiftsh(sld))
1506
1507         r_1 := 32 - srw
1508         r_2 := GetPPC64Shiftsh(sld)
1509         r_3 := (r_1 + r_2) & 31 // This can wrap.
1510
1511         if uint64(uint32(mask_3)) != mask_3 || mask_3 == 0 {
1512                 return 0
1513         }
1514         return encodePPC64RotateMask(int64(r_3), int64(mask_3), 32)
1515 }
1516
1517 // Test if a RLWINM feeding into a CLRLSLDI can be merged into RLWINM.  Return
1518 // the encoded RLWINM constant, or 0 if they cannot be merged.
1519 func mergePPC64ClrlsldiRlwinm(sld int32, rlw int64) int64 {
1520         r_1, _, _, mask_1 := DecodePPC64RotateMask(rlw)
1521         // for CLRLSLDI, it's more convient to think of it as a mask left bits then rotate left.
1522         mask_2 := uint64(0xFFFFFFFFFFFFFFFF) >> uint(GetPPC64Shiftmb(int64(sld)))
1523
1524         // combine the masks, and adjust for the final left shift.
1525         mask_3 := (mask_1 & mask_2) << uint(GetPPC64Shiftsh(int64(sld)))
1526         r_2 := GetPPC64Shiftsh(int64(sld))
1527         r_3 := (r_1 + r_2) & 31 // This can wrap.
1528
1529         // Verify the result is still a valid bitmask of <= 32 bits.
1530         if !isPPC64WordRotateMask(int64(mask_3)) || uint64(uint32(mask_3)) != mask_3 {
1531                 return 0
1532         }
1533         return encodePPC64RotateMask(r_3, int64(mask_3), 32)
1534 }
1535
1536 // Compute the encoded RLWINM constant from combining (SLDconst [sld] (SRWconst [srw] x)),
1537 // or return 0 if they cannot be combined.
1538 func mergePPC64SldiSrw(sld, srw int64) int64 {
1539         if sld > srw || srw >= 32 {
1540                 return 0
1541         }
1542         mask_r := uint32(0xFFFFFFFF) >> uint(srw)
1543         mask_l := uint32(0xFFFFFFFF) >> uint(sld)
1544         mask := (mask_r & mask_l) << uint(sld)
1545         return encodePPC64RotateMask((32-srw+sld)&31, int64(mask), 32)
1546 }
1547
1548 // Convenience function to rotate a 32 bit constant value by another constant.
1549 func rotateLeft32(v, rotate int64) int64 {
1550         return int64(bits.RotateLeft32(uint32(v), int(rotate)))
1551 }
1552
1553 // encodes the lsb and width for arm(64) bitfield ops into the expected auxInt format.
1554 func armBFAuxInt(lsb, width int64) arm64BitField {
1555         if lsb < 0 || lsb > 63 {
1556                 panic("ARM(64) bit field lsb constant out of range")
1557         }
1558         if width < 1 || width > 64 {
1559                 panic("ARM(64) bit field width constant out of range")
1560         }
1561         return arm64BitField(width | lsb<<8)
1562 }
1563
1564 // returns the lsb part of the auxInt field of arm64 bitfield ops.
1565 func (bfc arm64BitField) getARM64BFlsb() int64 {
1566         return int64(uint64(bfc) >> 8)
1567 }
1568
1569 // returns the width part of the auxInt field of arm64 bitfield ops.
1570 func (bfc arm64BitField) getARM64BFwidth() int64 {
1571         return int64(bfc) & 0xff
1572 }
1573
1574 // checks if mask >> rshift applied at lsb is a valid arm64 bitfield op mask.
1575 func isARM64BFMask(lsb, mask, rshift int64) bool {
1576         shiftedMask := int64(uint64(mask) >> uint64(rshift))
1577         return shiftedMask != 0 && isPowerOfTwo64(shiftedMask+1) && nto(shiftedMask)+lsb < 64
1578 }
1579
1580 // returns the bitfield width of mask >> rshift for arm64 bitfield ops
1581 func arm64BFWidth(mask, rshift int64) int64 {
1582         shiftedMask := int64(uint64(mask) >> uint64(rshift))
1583         if shiftedMask == 0 {
1584                 panic("ARM64 BF mask is zero")
1585         }
1586         return nto(shiftedMask)
1587 }
1588
1589 // sizeof returns the size of t in bytes.
1590 // It will panic if t is not a *types.Type.
1591 func sizeof(t interface{}) int64 {
1592         return t.(*types.Type).Size()
1593 }
1594
1595 // registerizable reports whether t is a primitive type that fits in
1596 // a register. It assumes float64 values will always fit into registers
1597 // even if that isn't strictly true.
1598 func registerizable(b *Block, typ *types.Type) bool {
1599         if typ.IsPtrShaped() || typ.IsFloat() {
1600                 return true
1601         }
1602         if typ.IsInteger() {
1603                 return typ.Size() <= b.Func.Config.RegSize
1604         }
1605         return false
1606 }
1607
1608 // needRaceCleanup reports whether this call to racefuncenter/exit isn't needed.
1609 func needRaceCleanup(sym *AuxCall, v *Value) bool {
1610         f := v.Block.Func
1611         if !f.Config.Race {
1612                 return false
1613         }
1614         if !isSameCall(sym, "runtime.racefuncenter") && !isSameCall(sym, "runtime.racefuncenterfp") && !isSameCall(sym, "runtime.racefuncexit") {
1615                 return false
1616         }
1617         for _, b := range f.Blocks {
1618                 for _, v := range b.Values {
1619                         switch v.Op {
1620                         case OpStaticCall:
1621                                 // Check for racefuncenter/racefuncenterfp will encounter racefuncexit and vice versa.
1622                                 // Allow calls to panic*
1623                                 s := v.Aux.(*AuxCall).Fn.String()
1624                                 switch s {
1625                                 case "runtime.racefuncenter", "runtime.racefuncenterfp", "runtime.racefuncexit",
1626                                         "runtime.panicdivide", "runtime.panicwrap",
1627                                         "runtime.panicshift":
1628                                         continue
1629                                 }
1630                                 // If we encountered any call, we need to keep racefunc*,
1631                                 // for accurate stacktraces.
1632                                 return false
1633                         case OpPanicBounds, OpPanicExtend:
1634                                 // Note: these are panic generators that are ok (like the static calls above).
1635                         case OpClosureCall, OpInterCall:
1636                                 // We must keep the race functions if there are any other call types.
1637                                 return false
1638                         }
1639                 }
1640         }
1641         if isSameCall(sym, "runtime.racefuncenter") {
1642                 // If we're removing racefuncenter, remove its argument as well.
1643                 if v.Args[0].Op != OpStore {
1644                         return false
1645                 }
1646                 mem := v.Args[0].Args[2]
1647                 v.Args[0].reset(OpCopy)
1648                 v.Args[0].AddArg(mem)
1649         }
1650         return true
1651 }
1652
1653 // symIsRO reports whether sym is a read-only global.
1654 func symIsRO(sym interface{}) bool {
1655         lsym := sym.(*obj.LSym)
1656         return lsym.Type == objabi.SRODATA && len(lsym.R) == 0
1657 }
1658
1659 // symIsROZero reports whether sym is a read-only global whose data contains all zeros.
1660 func symIsROZero(sym Sym) bool {
1661         lsym := sym.(*obj.LSym)
1662         if lsym.Type != objabi.SRODATA || len(lsym.R) != 0 {
1663                 return false
1664         }
1665         for _, b := range lsym.P {
1666                 if b != 0 {
1667                         return false
1668                 }
1669         }
1670         return true
1671 }
1672
1673 // read8 reads one byte from the read-only global sym at offset off.
1674 func read8(sym interface{}, off int64) uint8 {
1675         lsym := sym.(*obj.LSym)
1676         if off >= int64(len(lsym.P)) || off < 0 {
1677                 // Invalid index into the global sym.
1678                 // This can happen in dead code, so we don't want to panic.
1679                 // Just return any value, it will eventually get ignored.
1680                 // See issue 29215.
1681                 return 0
1682         }
1683         return lsym.P[off]
1684 }
1685
1686 // read16 reads two bytes from the read-only global sym at offset off.
1687 func read16(sym interface{}, off int64, byteorder binary.ByteOrder) uint16 {
1688         lsym := sym.(*obj.LSym)
1689         // lsym.P is written lazily.
1690         // Bytes requested after the end of lsym.P are 0.
1691         var src []byte
1692         if 0 <= off && off < int64(len(lsym.P)) {
1693                 src = lsym.P[off:]
1694         }
1695         buf := make([]byte, 2)
1696         copy(buf, src)
1697         return byteorder.Uint16(buf)
1698 }
1699
1700 // read32 reads four bytes from the read-only global sym at offset off.
1701 func read32(sym interface{}, off int64, byteorder binary.ByteOrder) uint32 {
1702         lsym := sym.(*obj.LSym)
1703         var src []byte
1704         if 0 <= off && off < int64(len(lsym.P)) {
1705                 src = lsym.P[off:]
1706         }
1707         buf := make([]byte, 4)
1708         copy(buf, src)
1709         return byteorder.Uint32(buf)
1710 }
1711
1712 // read64 reads eight bytes from the read-only global sym at offset off.
1713 func read64(sym interface{}, off int64, byteorder binary.ByteOrder) uint64 {
1714         lsym := sym.(*obj.LSym)
1715         var src []byte
1716         if 0 <= off && off < int64(len(lsym.P)) {
1717                 src = lsym.P[off:]
1718         }
1719         buf := make([]byte, 8)
1720         copy(buf, src)
1721         return byteorder.Uint64(buf)
1722 }
1723
1724 // sequentialAddresses reports true if it can prove that x + n == y
1725 func sequentialAddresses(x, y *Value, n int64) bool {
1726         if x.Op == Op386ADDL && y.Op == Op386LEAL1 && y.AuxInt == n && y.Aux == nil &&
1727                 (x.Args[0] == y.Args[0] && x.Args[1] == y.Args[1] ||
1728                         x.Args[0] == y.Args[1] && x.Args[1] == y.Args[0]) {
1729                 return true
1730         }
1731         if x.Op == Op386LEAL1 && y.Op == Op386LEAL1 && y.AuxInt == x.AuxInt+n && x.Aux == y.Aux &&
1732                 (x.Args[0] == y.Args[0] && x.Args[1] == y.Args[1] ||
1733                         x.Args[0] == y.Args[1] && x.Args[1] == y.Args[0]) {
1734                 return true
1735         }
1736         if x.Op == OpAMD64ADDQ && y.Op == OpAMD64LEAQ1 && y.AuxInt == n && y.Aux == nil &&
1737                 (x.Args[0] == y.Args[0] && x.Args[1] == y.Args[1] ||
1738                         x.Args[0] == y.Args[1] && x.Args[1] == y.Args[0]) {
1739                 return true
1740         }
1741         if x.Op == OpAMD64LEAQ1 && y.Op == OpAMD64LEAQ1 && y.AuxInt == x.AuxInt+n && x.Aux == y.Aux &&
1742                 (x.Args[0] == y.Args[0] && x.Args[1] == y.Args[1] ||
1743                         x.Args[0] == y.Args[1] && x.Args[1] == y.Args[0]) {
1744                 return true
1745         }
1746         return false
1747 }
1748
1749 // flagConstant represents the result of a compile-time comparison.
1750 // The sense of these flags does not necessarily represent the hardware's notion
1751 // of a flags register - these are just a compile-time construct.
1752 // We happen to match the semantics to those of arm/arm64.
1753 // Note that these semantics differ from x86: the carry flag has the opposite
1754 // sense on a subtraction!
1755 //   On amd64, C=1 represents a borrow, e.g. SBB on amd64 does x - y - C.
1756 //   On arm64, C=0 represents a borrow, e.g. SBC on arm64 does x - y - ^C.
1757 //    (because it does x + ^y + C).
1758 // See https://en.wikipedia.org/wiki/Carry_flag#Vs._borrow_flag
1759 type flagConstant uint8
1760
1761 // N reports whether the result of an operation is negative (high bit set).
1762 func (fc flagConstant) N() bool {
1763         return fc&1 != 0
1764 }
1765
1766 // Z reports whether the result of an operation is 0.
1767 func (fc flagConstant) Z() bool {
1768         return fc&2 != 0
1769 }
1770
1771 // C reports whether an unsigned add overflowed (carry), or an
1772 // unsigned subtract did not underflow (borrow).
1773 func (fc flagConstant) C() bool {
1774         return fc&4 != 0
1775 }
1776
1777 // V reports whether a signed operation overflowed or underflowed.
1778 func (fc flagConstant) V() bool {
1779         return fc&8 != 0
1780 }
1781
1782 func (fc flagConstant) eq() bool {
1783         return fc.Z()
1784 }
1785 func (fc flagConstant) ne() bool {
1786         return !fc.Z()
1787 }
1788 func (fc flagConstant) lt() bool {
1789         return fc.N() != fc.V()
1790 }
1791 func (fc flagConstant) le() bool {
1792         return fc.Z() || fc.lt()
1793 }
1794 func (fc flagConstant) gt() bool {
1795         return !fc.Z() && fc.ge()
1796 }
1797 func (fc flagConstant) ge() bool {
1798         return fc.N() == fc.V()
1799 }
1800 func (fc flagConstant) ult() bool {
1801         return !fc.C()
1802 }
1803 func (fc flagConstant) ule() bool {
1804         return fc.Z() || fc.ult()
1805 }
1806 func (fc flagConstant) ugt() bool {
1807         return !fc.Z() && fc.uge()
1808 }
1809 func (fc flagConstant) uge() bool {
1810         return fc.C()
1811 }
1812
1813 func (fc flagConstant) ltNoov() bool {
1814         return fc.lt() && !fc.V()
1815 }
1816 func (fc flagConstant) leNoov() bool {
1817         return fc.le() && !fc.V()
1818 }
1819 func (fc flagConstant) gtNoov() bool {
1820         return fc.gt() && !fc.V()
1821 }
1822 func (fc flagConstant) geNoov() bool {
1823         return fc.ge() && !fc.V()
1824 }
1825
1826 func (fc flagConstant) String() string {
1827         return fmt.Sprintf("N=%v,Z=%v,C=%v,V=%v", fc.N(), fc.Z(), fc.C(), fc.V())
1828 }
1829
1830 type flagConstantBuilder struct {
1831         N bool
1832         Z bool
1833         C bool
1834         V bool
1835 }
1836
1837 func (fcs flagConstantBuilder) encode() flagConstant {
1838         var fc flagConstant
1839         if fcs.N {
1840                 fc |= 1
1841         }
1842         if fcs.Z {
1843                 fc |= 2
1844         }
1845         if fcs.C {
1846                 fc |= 4
1847         }
1848         if fcs.V {
1849                 fc |= 8
1850         }
1851         return fc
1852 }
1853
1854 // Note: addFlags(x,y) != subFlags(x,-y) in some situations:
1855 //  - the results of the C flag are different
1856 //  - the results of the V flag when y==minint are different
1857
1858 // addFlags64 returns the flags that would be set from computing x+y.
1859 func addFlags64(x, y int64) flagConstant {
1860         var fcb flagConstantBuilder
1861         fcb.Z = x+y == 0
1862         fcb.N = x+y < 0
1863         fcb.C = uint64(x+y) < uint64(x)
1864         fcb.V = x >= 0 && y >= 0 && x+y < 0 || x < 0 && y < 0 && x+y >= 0
1865         return fcb.encode()
1866 }
1867
1868 // subFlags64 returns the flags that would be set from computing x-y.
1869 func subFlags64(x, y int64) flagConstant {
1870         var fcb flagConstantBuilder
1871         fcb.Z = x-y == 0
1872         fcb.N = x-y < 0
1873         fcb.C = uint64(y) <= uint64(x) // This code follows the arm carry flag model.
1874         fcb.V = x >= 0 && y < 0 && x-y < 0 || x < 0 && y >= 0 && x-y >= 0
1875         return fcb.encode()
1876 }
1877
1878 // addFlags32 returns the flags that would be set from computing x+y.
1879 func addFlags32(x, y int32) flagConstant {
1880         var fcb flagConstantBuilder
1881         fcb.Z = x+y == 0
1882         fcb.N = x+y < 0
1883         fcb.C = uint32(x+y) < uint32(x)
1884         fcb.V = x >= 0 && y >= 0 && x+y < 0 || x < 0 && y < 0 && x+y >= 0
1885         return fcb.encode()
1886 }
1887
1888 // subFlags32 returns the flags that would be set from computing x-y.
1889 func subFlags32(x, y int32) flagConstant {
1890         var fcb flagConstantBuilder
1891         fcb.Z = x-y == 0
1892         fcb.N = x-y < 0
1893         fcb.C = uint32(y) <= uint32(x) // This code follows the arm carry flag model.
1894         fcb.V = x >= 0 && y < 0 && x-y < 0 || x < 0 && y >= 0 && x-y >= 0
1895         return fcb.encode()
1896 }
1897
1898 // logicFlags64 returns flags set to the sign/zeroness of x.
1899 // C and V are set to false.
1900 func logicFlags64(x int64) flagConstant {
1901         var fcb flagConstantBuilder
1902         fcb.Z = x == 0
1903         fcb.N = x < 0
1904         return fcb.encode()
1905 }
1906
1907 // logicFlags32 returns flags set to the sign/zeroness of x.
1908 // C and V are set to false.
1909 func logicFlags32(x int32) flagConstant {
1910         var fcb flagConstantBuilder
1911         fcb.Z = x == 0
1912         fcb.N = x < 0
1913         return fcb.encode()
1914 }