// Derived from Inferno utils/6c/peep.c
// http://code.google.com/p/inferno-os/source/browse/utils/6c/peep.c
//
//	Copyright © 1994-1999 Lucent Technologies Inc.  All rights reserved.
//	Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net)
//	Portions Copyright © 1997-1999 Vita Nuova Limited
//	Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com)
//	Portions Copyright © 2004,2006 Bruce Ellis
//	Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net)
//	Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others
//	Portions Copyright © 2009 The Go Authors.  All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.

package s390x

import (
	"cmd/compile/internal/gc"
	"cmd/internal/obj"
	"cmd/internal/obj/s390x"
	"fmt"
)

type usage int

const (
	_None          usage = iota // no usage found
	_Read                       // only read from
	_ReadWriteSame              // both read from and written to in a single operand
	_Write                      // only written to
	_ReadWriteDiff              // both read from and written to in different operands
)

var gactive uint32

func peep(firstp *obj.Prog) {
	g := gc.Flowstart(firstp, nil)
	if g == nil {
		return
	}
	gactive = 0

	run := func(name string, pass func(r *gc.Flow) int) int {
		n := pass(g.Start)
		if gc.Debug['P'] != 0 {
			fmt.Println(name, ":", n)
		}
		if gc.Debug['P'] != 0 && gc.Debug['v'] != 0 {
			gc.Dumpit(name, g.Start, 0)
		}
		return n
	}

	for {
		n := 0
		n += run("constant propagation", constantPropagation)
		n += run("copy propagation", copyPropagation)
		n += run("cast propagation", castPropagation)
		n += run("remove load-hit-stores", removeLoadHitStores)
		n += run("dead code elimination", deadCodeElimination)
		if n == 0 {
			break
		}
	}
	run("fuse op moves", fuseOpMoves)
	run("fuse clears", fuseClear)
	run("load pipelining", loadPipelining)
	run("fuse compare branch", fuseCompareBranch)
	run("simplify ops", simplifyOps)
	run("dead code elimination", deadCodeElimination)

	// TODO(mundaym): load/store multiple aren't currently handled by copyu
	// so this pass must be last.
	run("fuse multiple", fuseMultiple)

	gc.Flowend(g)
}

func pushback(r0 *gc.Flow) {
	var r *gc.Flow

	var b *gc.Flow
	p0 := r0.Prog
	for r = gc.Uniqp(r0); r != nil && gc.Uniqs(r) != nil; r = gc.Uniqp(r) {
		p := r.Prog
		if p.As != obj.ANOP {
			if !(isReg(&p.From) || isConst(&p.From)) || !isReg(&p.To) {
				break
			}
			if copyu(p, &p0.To, nil) != _None || copyu(p0, &p.To, nil) != _None {
				break
			}
		}

		if p.As == obj.ACALL {
			break
		}
		b = r
	}

	if b == nil {
		if gc.Debug['P'] != 0 && gc.Debug['v'] != 0 {
			fmt.Printf("no pushback: %v\n", r0.Prog)
			if r != nil {
				fmt.Printf("\t%v [%v]\n", r.Prog, gc.Uniqs(r) != nil)
			}
		}

		return
	}

	if gc.Debug['P'] != 0 && gc.Debug['v'] != 0 {
		fmt.Printf("pushback\n")
		for r := b; ; r = r.Link {
			fmt.Printf("\t%v\n", r.Prog)
			if r == r0 {
				break
			}
		}
	}

	t := *r0.Prog
	for r = gc.Uniqp(r0); ; r = gc.Uniqp(r) {
		p0 = r.Link.Prog
		p := r.Prog
		p0.As = p.As
		p0.Lineno = p.Lineno
		p0.From = p.From
		p0.To = p.To
		p0.From3 = p.From3
		p0.Reg = p.Reg
		p0.RegTo2 = p.RegTo2
		if r == b {
			break
		}
	}

	p0 = r.Prog
	p0.As = t.As
	p0.Lineno = t.Lineno
	p0.From = t.From
	p0.To = t.To
	p0.From3 = t.From3
	p0.Reg = t.Reg
	p0.RegTo2 = t.RegTo2

	if gc.Debug['P'] != 0 && gc.Debug['v'] != 0 {
		fmt.Printf("\tafter\n")
		for r := b; ; r = r.Link {
			fmt.Printf("\t%v\n", r.Prog)
			if r == r0 {
				break
			}
		}
	}
}

// excise replaces the given instruction with a NOP and clears
// its operands.
func excise(r *gc.Flow) {
	p := r.Prog
	if gc.Debug['P'] != 0 && gc.Debug['v'] != 0 {
		fmt.Printf("%v ===delete===\n", p)
	}
	obj.Nopout(p)
	gc.Ostats.Ndelmov++
}

// isZero returns true if a is either the constant 0 or the register
// REGZERO.
func isZero(a *obj.Addr) bool {
	if a.Type == obj.TYPE_CONST && a.Offset == 0 {
		return true
	}
	if a.Type == obj.TYPE_REG && a.Reg == s390x.REGZERO {
		return true
	}
	return false
}

// isReg returns true if a is a general purpose or floating point
// register (GPR or FPR).
//
// TODO(mundaym): currently this excludes REGZER0, but not other
// special registers.
func isReg(a *obj.Addr) bool {
	return a.Type == obj.TYPE_REG &&
		s390x.REG_R0 <= a.Reg &&
		a.Reg <= s390x.REG_F15 &&
		a.Reg != s390x.REGZERO
}

// isGPR returns true if a is a general purpose register (GPR).
// REGZERO is treated as a GPR.
func isGPR(a *obj.Addr) bool {
	return a.Type == obj.TYPE_REG &&
		s390x.REG_R0 <= a.Reg &&
		a.Reg <= s390x.REG_R15
}

// isFPR returns true if a is a floating point register (FPR).
func isFPR(a *obj.Addr) bool {
	return a.Type == obj.TYPE_REG &&
		s390x.REG_F0 <= a.Reg &&
		a.Reg <= s390x.REG_F15
}

// isConst returns true if a refers to a constant (integer or
// floating point, not string currently).
func isConst(a *obj.Addr) bool {
	return a.Type == obj.TYPE_CONST || a.Type == obj.TYPE_FCONST
}

// isBDMem returns true if a refers to a memory location addressable by a
// base register (B) and a displacement (D), such as:
// 	x+8(R1)
// and
//	0(R10)
// It returns false if the address contains an index register (X) such as:
// 	16(R1)(R2*1)
// or if a relocation is required.
func isBDMem(a *obj.Addr) bool {
	return a.Type == obj.TYPE_MEM &&
		a.Index == 0 &&
		(a.Name == obj.NAME_NONE || a.Name == obj.NAME_AUTO || a.Name == obj.NAME_PARAM)
}

// the idea is to substitute
// one register for another
// from one MOV to another
//	MOV	a, R1
//	ADD	b, R1	/ no use of R2
//	MOV	R1, R2
// would be converted to
//	MOV	a, R2
//	ADD	b, R2
//	MOV	R2, R1
// hopefully, then the former or latter MOV
// will be eliminated by copy propagation.
//
// r0 (the argument, not the register) is the MOV at the end of the
// above sequences. subprop returns true if it modified any instructions.
func subprop(r0 *gc.Flow) bool {
	p := r0.Prog
	v1 := &p.From
	if !isReg(v1) {
		return false
	}
	v2 := &p.To
	if !isReg(v2) {
		return false
	}
	cast := false
	switch p.As {
	case s390x.AMOVW, s390x.AMOVWZ,
		s390x.AMOVH, s390x.AMOVHZ,
		s390x.AMOVB, s390x.AMOVBZ:
		cast = true
	}
	for r := gc.Uniqp(r0); r != nil; r = gc.Uniqp(r) {
		if gc.Uniqs(r) == nil {
			break
		}
		p = r.Prog
		switch copyu(p, v1, nil) {
		case _Write, _ReadWriteDiff:
			if p.As == obj.ACALL {
				return false
			}
			if (!cast || p.As == r0.Prog.As) && p.To.Type == v1.Type && p.To.Reg == v1.Reg {
				copysub(&p.To, v1, v2)
				for r = gc.Uniqs(r); r != r0; r = gc.Uniqs(r) {
					p = r.Prog
					copysub(&p.From, v1, v2)
					copysub1(p, v1, v2)
					copysub(&p.To, v1, v2)
				}
				v1.Reg, v2.Reg = v2.Reg, v1.Reg
				return true
			}
			if cast {
				return false
			}
		case _ReadWriteSame:
			if cast {
				return false
			}
		}
		if copyu(p, v2, nil) != _None {
			return false
		}
	}
	return false
}

// The idea is to remove redundant copies.
//     v1->v2  F=0
//     (use v2 s/v2/v1/)*
//     set v1  F=1
//     use v2  return fail (v1->v2 move must remain)
//     -----------------
//     v1->v2  F=0
//     (use v2 s/v2/v1/)*
//     set v1  F=1
//     set v2  return success (caller can remove v1->v2 move)
func copyprop(r *gc.Flow) bool {
	p := r.Prog

	canSub := false
	switch p.As {
	case s390x.AFMOVS, s390x.AFMOVD, s390x.AMOVD:
		canSub = true
	default:
		for rr := gc.Uniqp(r); rr != nil; rr = gc.Uniqp(rr) {
			if gc.Uniqs(rr) == nil {
				break
			}
			switch copyu(rr.Prog, &p.From, nil) {
			case _Read, _None:
				continue
			}
			// write
			if rr.Prog.As == p.As {
				canSub = true
			}
			break
		}
	}
	if !canSub {
		return false
	}
	if copyas(&p.From, &p.To) {
		return true
	}

	gactive++
	return copy1(&p.From, &p.To, r.S1, 0)
}

// copy1 replaces uses of v2 with v1 starting at r and returns true if
// all uses were rewritten.
func copy1(v1 *obj.Addr, v2 *obj.Addr, r *gc.Flow, f int) bool {
	if uint32(r.Active) == gactive {
		return true
	}
	r.Active = int32(gactive)
	for ; r != nil; r = r.S1 {
		p := r.Prog
		if f == 0 && gc.Uniqp(r) == nil {
			// Multiple predecessors; conservatively
			// assume v1 was set on other path
			f = 1
		}
		t := copyu(p, v2, nil)
		switch t {
		case _ReadWriteSame:
			return false
		case _Write:
			return true
		case _Read, _ReadWriteDiff:
			if f != 0 {
				return false
			}
			if copyu(p, v2, v1) != 0 {
				return false
			}
			if t == _ReadWriteDiff {
				return true
			}
		}
		if f == 0 {
			switch copyu(p, v1, nil) {
			case _ReadWriteSame, _ReadWriteDiff, _Write:
				f = 1
			}
		}
		if r.S2 != nil {
			if !copy1(v1, v2, r.S2, f) {
				return false
			}
		}
	}
	return true
}

// If s==nil, copyu returns the set/use of v in p; otherwise, it
// modifies p to replace reads of v with reads of s and returns 0 for
// success or non-zero for failure.
//
// If s==nil, copy returns one of the following values:
// 	_Read           if v only used
//	_ReadWriteSame  if v is set and used in one address (read-alter-rewrite;
// 	                can't substitute)
//	_Write          if v is only set
//	_ReadWriteDiff  if v is set in one address and used in another (so addresses
// 	                can be rewritten independently)
//	_None           otherwise (not touched)
func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) usage {
	if p.From3Type() != obj.TYPE_NONE && p.From3Type() != obj.TYPE_CONST {
		// Currently we never generate a From3 with anything other than a constant in it.
		fmt.Printf("copyu: From3 (%v) not implemented\n", gc.Ctxt.Dconv(p.From3))
	}

	switch p.As {
	default:
		fmt.Printf("copyu: can't find %v\n", p.As)
		return _ReadWriteSame

	case // read p.From, write p.To
		s390x.AMOVH,
		s390x.AMOVHZ,
		s390x.AMOVB,
		s390x.AMOVBZ,
		s390x.AMOVW,
		s390x.AMOVWZ,
		s390x.AMOVD,
		s390x.ANEG,
		s390x.AADDME,
		s390x.AADDZE,
		s390x.ASUBME,
		s390x.ASUBZE,
		s390x.AFMOVS,
		s390x.AFMOVD,
		s390x.ALEDBR,
		s390x.AFNEG,
		s390x.ALDEBR,
		s390x.ACLFEBR,
		s390x.ACLGEBR,
		s390x.ACLFDBR,
		s390x.ACLGDBR,
		s390x.ACFEBRA,
		s390x.ACGEBRA,
		s390x.ACFDBRA,
		s390x.ACGDBRA,
		s390x.ACELFBR,
		s390x.ACELGBR,
		s390x.ACDLFBR,
		s390x.ACDLGBR,
		s390x.ACEFBRA,
		s390x.ACEGBRA,
		s390x.ACDFBRA,
		s390x.ACDGBRA,
		s390x.AFSQRT:

		if s != nil {
			copysub(&p.From, v, s)

			// Update only indirect uses of v in p.To
			if !copyas(&p.To, v) {
				copysub(&p.To, v, s)
			}
			return _None
		}

		if copyas(&p.To, v) {
			// Fix up implicit from
			if p.From.Type == obj.TYPE_NONE {
				p.From = p.To
			}
			if copyau(&p.From, v) {
				return _ReadWriteDiff
			}
			return _Write
		}

		if copyau(&p.From, v) {
			return _Read
		}
		if copyau(&p.To, v) {
			// p.To only indirectly uses v
			return _Read
		}

		return _None

	// read p.From, read p.Reg, write p.To
	case s390x.AADD,
		s390x.AADDC,
		s390x.AADDE,
		s390x.ASUB,
		s390x.ASLW,
		s390x.ASRW,
		s390x.ASRAW,
		s390x.ASLD,
		s390x.ASRD,
		s390x.ASRAD,
		s390x.ARLL,
		s390x.ARLLG,
		s390x.AOR,
		s390x.AORN,
		s390x.AAND,
		s390x.AANDN,
		s390x.ANAND,
		s390x.ANOR,
		s390x.AXOR,
		s390x.AMULLW,
		s390x.AMULLD,
		s390x.AMULHD,
		s390x.AMULHDU,
		s390x.ADIVW,
		s390x.ADIVD,
		s390x.ADIVWU,
		s390x.ADIVDU,
		s390x.AFADDS,
		s390x.AFADD,
		s390x.AFSUBS,
		s390x.AFSUB,
		s390x.AFMULS,
		s390x.AFMUL,
		s390x.AFDIVS,
		s390x.AFDIV:
		if s != nil {
			copysub(&p.From, v, s)
			copysub1(p, v, s)

			// Update only indirect uses of v in p.To
			if !copyas(&p.To, v) {
				copysub(&p.To, v, s)
			}
		}

		if copyas(&p.To, v) {
			if p.Reg == 0 {
				p.Reg = p.To.Reg
			}
			if copyau(&p.From, v) || copyau1(p, v) {
				return _ReadWriteDiff
			}
			return _Write
		}

		if copyau(&p.From, v) {
			return _Read
		}
		if copyau1(p, v) {
			return _Read
		}
		if copyau(&p.To, v) {
			return _Read
		}
		return _None

	case s390x.ABEQ,
		s390x.ABGT,
		s390x.ABGE,
		s390x.ABLT,
		s390x.ABLE,
		s390x.ABNE,
		s390x.ABVC,
		s390x.ABVS:
		return _None

	case obj.ACHECKNIL, // read p.From
		s390x.ACMP, // read p.From, read p.To
		s390x.ACMPU,
		s390x.ACMPW,
		s390x.ACMPWU,
		s390x.AFCMPO,
		s390x.AFCMPU,
		s390x.ACEBR,
		s390x.AMVC,
		s390x.ACLC,
		s390x.AXC,
		s390x.AOC,
		s390x.ANC:
		if s != nil {
			copysub(&p.From, v, s)
			copysub(&p.To, v, s)
			return _None
		}

		if copyau(&p.From, v) {
			return _Read
		}
		if copyau(&p.To, v) {
			return _Read
		}
		return _None

	case s390x.ACMPBNE, s390x.ACMPBEQ,
		s390x.ACMPBLT, s390x.ACMPBLE,
		s390x.ACMPBGT, s390x.ACMPBGE,
		s390x.ACMPUBNE, s390x.ACMPUBEQ,
		s390x.ACMPUBLT, s390x.ACMPUBLE,
		s390x.ACMPUBGT, s390x.ACMPUBGE:
		if s != nil {
			copysub(&p.From, v, s)
			copysub1(p, v, s)
			return _None
		}
		if copyau(&p.From, v) {
			return _Read
		}
		if copyau1(p, v) {
			return _Read
		}
		return _None

	case s390x.ACLEAR:
		if s != nil {
			copysub(&p.To, v, s)
			return _None
		}
		if copyau(&p.To, v) {
			return _Read
		}
		return _None

	// go never generates a branch to a GPR
	// read p.To
	case s390x.ABR:
		if s != nil {
			copysub(&p.To, v, s)
			return _None
		}

		if copyau(&p.To, v) {
			return _Read
		}
		return _None

	case obj.ARET, obj.AUNDEF:
		if s != nil {
			return _None
		}

		// All registers die at this point, so claim
		// everything is set (and not used).
		return _Write

	case s390x.ABL:
		if v.Type == obj.TYPE_REG {
			if s390x.REGARG != -1 && v.Reg == s390x.REGARG {
				return _ReadWriteSame
			}
			if p.From.Type == obj.TYPE_REG && p.From.Reg == v.Reg {
				return _ReadWriteSame
			}
			if v.Reg == s390x.REGZERO {
				// Deliberately inserted nops set R0.
				return _ReadWriteSame
			}
			if v.Reg == s390x.REGCTXT {
				// Context register for closures.
				// TODO(mundaym): not sure if we need to exclude this.
				return _ReadWriteSame
			}
		}
		if s != nil {
			copysub(&p.To, v, s)
			return _None
		}
		if copyau(&p.To, v) {
			return _ReadWriteDiff
		}
		return _Write

	case obj.ATEXT:
		if v.Type == obj.TYPE_REG {
			if v.Reg == s390x.REGARG {
				return _Write
			}
		}
		return _None

	case obj.APCDATA,
		obj.AFUNCDATA,
		obj.AVARDEF,
		obj.AVARKILL,
		obj.AVARLIVE,
		obj.AUSEFIELD,
		obj.ANOP:
		return _None
	}
}

// copyas returns 1 if a and v address the same register.
//
// If a is the from operand, this means this operation reads the
// register in v.  If a is the to operand, this means this operation
// writes the register in v.
func copyas(a *obj.Addr, v *obj.Addr) bool {
	if isReg(v) {
		if a.Type == v.Type {
			if a.Reg == v.Reg {
				return true
			}
		}
	}
	return false
}

// copyau returns 1 if a either directly or indirectly addresses the
// same register as v.
//
// If a is the from operand, this means this operation reads the
// register in v.  If a is the to operand, this means the operation
// either reads or writes the register in v (if !copyas(a, v), then
// the operation reads the register in v).
func copyau(a *obj.Addr, v *obj.Addr) bool {
	if copyas(a, v) {
		return true
	}
	if v.Type == obj.TYPE_REG {
		if a.Type == obj.TYPE_MEM || (a.Type == obj.TYPE_ADDR && a.Reg != 0) {
			if v.Reg == a.Reg {
				return true
			}
		}
	}
	return false
}

// copyau1 returns 1 if p.Reg references the same register as v and v
// is a direct reference.
func copyau1(p *obj.Prog, v *obj.Addr) bool {
	if isReg(v) && v.Reg != 0 {
		if p.Reg == v.Reg {
			return true
		}
	}
	return false
}

// copysub replaces v.Reg with s.Reg if a.Reg and v.Reg are direct
// references to the same register.
func copysub(a, v, s *obj.Addr) {
	if copyau(a, v) {
		a.Reg = s.Reg
	}
}

// copysub1 replaces p.Reg with s.Reg if p.Reg and v.Reg are direct
// references to the same register.
func copysub1(p *obj.Prog, v, s *obj.Addr) {
	if copyau1(p, v) {
		p.Reg = s.Reg
	}
}

func sameaddr(a *obj.Addr, v *obj.Addr) bool {
	if a.Type != v.Type {
		return false
	}
	if isReg(v) && a.Reg == v.Reg {
		return true
	}
	if v.Type == obj.NAME_AUTO || v.Type == obj.NAME_PARAM {
		// TODO(mundaym): is the offset enough here? Node?
		if v.Offset == a.Offset {
			return true
		}
	}
	return false
}

func smallindir(a *obj.Addr, reg *obj.Addr) bool {
	return reg.Type == obj.TYPE_REG &&
		a.Type == obj.TYPE_MEM &&
		a.Reg == reg.Reg &&
		0 <= a.Offset && a.Offset < 4096
}

func stackaddr(a *obj.Addr) bool {
	// TODO(mundaym): the name implies this should check
	// for TYPE_ADDR with a base register REGSP.
	return a.Type == obj.TYPE_REG && a.Reg == s390x.REGSP
}

// isMove returns true if p is a move. Moves may imply
// sign/zero extension.
func isMove(p *obj.Prog) bool {
	switch p.As {
	case s390x.AMOVD,
		s390x.AMOVW, s390x.AMOVWZ,
		s390x.AMOVH, s390x.AMOVHZ,
		s390x.AMOVB, s390x.AMOVBZ,
		s390x.AFMOVD, s390x.AFMOVS:
		return true
	}
	return false
}

// isLoad returns true if p is a move from memory to a register.
func isLoad(p *obj.Prog) bool {
	if !isMove(p) {
		return false
	}
	if !(isGPR(&p.To) || isFPR(&p.To)) {
		return false
	}
	if p.From.Type != obj.TYPE_MEM {
		return false
	}
	return true
}

// isStore returns true if p is a move from a register to memory.
func isStore(p *obj.Prog) bool {
	if !isMove(p) {
		return false
	}
	if !(isGPR(&p.From) || isFPR(&p.From) || isConst(&p.From)) {
		return false
	}
	if p.To.Type != obj.TYPE_MEM {
		return false
	}
	return true
}

// sameStackMem returns true if a and b are both memory operands
// and address the same location which must reside on the stack.
func sameStackMem(a, b *obj.Addr) bool {
	if a.Type != obj.TYPE_MEM ||
		b.Type != obj.TYPE_MEM ||
		a.Name != b.Name ||
		a.Sym != b.Sym ||
		a.Node != b.Node ||
		a.Reg != b.Reg ||
		a.Index != b.Index ||
		a.Offset != b.Offset {
		return false
	}
	switch a.Name {
	case obj.NAME_NONE:
		return a.Reg == s390x.REGSP
	case obj.NAME_PARAM, obj.NAME_AUTO:
		// params and autos are always on the stack
		return true
	}
	return false
}

// removeLoadHitStores trys to remove loads that take place
// immediately after a store to the same location. Returns
// true if load-hit-stores were removed.
//
// For example:
// 	MOVD	R1, 0(R15)
// 	MOVD	0(R15), R2
// Would become:
// 	MOVD	R1, 0(R15)
// 	MOVD	R1, R2
func removeLoadHitStores(r *gc.Flow) int {
	n := 0
	for ; r != nil; r = r.Link {
		p := r.Prog
		if !isStore(p) {
			continue
		}
		for rr := gc.Uniqs(r); rr != nil; rr = gc.Uniqs(rr) {
			pp := rr.Prog
			if gc.Uniqp(rr) == nil {
				break
			}
			if pp.As == obj.ANOP {
				continue
			}
			if isLoad(pp) && sameStackMem(&p.To, &pp.From) {
				if size(p.As) >= size(pp.As) && isGPR(&p.From) == isGPR(&pp.To) {
					pp.From = p.From
				}
			}
			if !isMove(pp) || isStore(pp) {
				break
			}
			if copyau(&p.From, &pp.To) {
				break
			}
		}
	}
	return n
}

// size returns the width of the given move.
func size(as obj.As) int {
	switch as {
	case s390x.AMOVD, s390x.AFMOVD:
		return 8
	case s390x.AMOVW, s390x.AMOVWZ, s390x.AFMOVS:
		return 4
	case s390x.AMOVH, s390x.AMOVHZ:
		return 2
	case s390x.AMOVB, s390x.AMOVBZ:
		return 1
	}
	return -1
}

// castPropagation tries to eliminate unecessary casts.
//
// For example:
// 	MOVHZ	R1, R2     // uint16
//	MOVB	R2, 0(R15) // int8
// Can be simplified to:
//	MOVB	R1, 0(R15)
func castPropagation(r *gc.Flow) int {
	n := 0
	for ; r != nil; r = r.Link {
		p := r.Prog
		if !isMove(p) || !isGPR(&p.To) {
			continue
		}

		// r is a move with a destination register
		var move *gc.Flow
		for rr := gc.Uniqs(r); rr != nil; rr = gc.Uniqs(rr) {
			if gc.Uniqp(rr) == nil {
				// branch target: leave alone
				break
			}
			pp := rr.Prog
			if isMove(pp) && copyas(&pp.From, &p.To) {
				if pp.To.Type == obj.TYPE_MEM {
					if p.From.Type == obj.TYPE_MEM ||
						p.From.Type == obj.TYPE_ADDR {
						break
					}
					if p.From.Type == obj.TYPE_CONST &&
						int64(int16(p.From.Offset)) != p.From.Offset {
						break
					}
				}
				move = rr
				break
			}
			if pp.As == obj.ANOP {
				continue
			}
			break
		}
		if move == nil {
			continue
		}

		// we have a move that reads from our destination reg, check if any future
		// instructions also read from the reg
		mp := move.Prog
		if !copyas(&mp.From, &mp.To) {
			safe := false
			for rr := gc.Uniqs(move); rr != nil; rr = gc.Uniqs(rr) {
				if gc.Uniqp(rr) == nil {
					break
				}
				switch copyu(rr.Prog, &p.To, nil) {
				case _None:
					continue
				case _Write:
					safe = true
				}
				break
			}
			if !safe {
				continue
			}
		}

		// at this point we have something like:
		// MOV* const/mem/reg, reg
		// MOV* reg, reg/mem
		// now check if this is a cast that cannot be forward propagated
		execute := false
		if p.As == mp.As || isZero(&p.From) || size(p.As) == size(mp.As) {
			execute = true
		} else if isGPR(&p.From) && size(p.As) >= size(mp.As) {
			execute = true
		}

		if execute {
			mp.From = p.From
			excise(r)
			n++
		}
	}
	return n
}

// fuseClear merges memory clear operations.
//
// Looks for this pattern (sequence of clears):
// 	MOVD	R0, n(R15)
// 	MOVD	R0, n+8(R15)
// 	MOVD	R0, n+16(R15)
// Replaces with:
//	CLEAR	$24, n(R15)
func fuseClear(r *gc.Flow) int {
	n := 0
	var align int64
	var clear *obj.Prog
	for ; r != nil; r = r.Link {
		// If there is a branch into the instruction stream then
		// we can't fuse into previous instructions.
		if gc.Uniqp(r) == nil {
			clear = nil
		}

		p := r.Prog
		if p.As == obj.ANOP {
			continue
		}
		if p.As == s390x.AXC {
			if p.From.Reg == p.To.Reg && p.From.Offset == p.To.Offset {
				// TODO(mundaym): merge clears?
				p.As = s390x.ACLEAR
				p.From.Offset = p.From3.Offset
				p.From3 = nil
				p.From.Type = obj.TYPE_CONST
				p.From.Reg = 0
				clear = p
			} else {
				clear = nil
			}
			continue
		}

		// Is our source a constant zero?
		if !isZero(&p.From) {
			clear = nil
			continue
		}

		// Are we moving to memory?
		if p.To.Type != obj.TYPE_MEM ||
			p.To.Index != 0 ||
			p.To.Offset >= 4096 ||
			!(p.To.Name == obj.NAME_NONE || p.To.Name == obj.NAME_AUTO || p.To.Name == obj.NAME_PARAM) {
			clear = nil
			continue
		}

		size := int64(0)
		switch p.As {
		default:
			clear = nil
			continue
		case s390x.AMOVB, s390x.AMOVBZ:
			size = 1
		case s390x.AMOVH, s390x.AMOVHZ:
			size = 2
		case s390x.AMOVW, s390x.AMOVWZ:
			size = 4
		case s390x.AMOVD:
			size = 8
		}

		// doubleword aligned clears should be kept doubleword
		// aligned
		if (size == 8 && align != 8) || (size != 8 && align == 8) {
			clear = nil
		}

		if clear != nil &&
			clear.To.Reg == p.To.Reg &&
			clear.To.Name == p.To.Name &&
			clear.To.Node == p.To.Node &&
			clear.To.Sym == p.To.Sym {

			min := clear.To.Offset
			max := clear.To.Offset + clear.From.Offset

			// previous clear is already clearing this region
			if min <= p.To.Offset && max >= p.To.Offset+size {
				excise(r)
				n++
				continue
			}

			// merge forwards
			if max == p.To.Offset {
				clear.From.Offset += size
				excise(r)
				n++
				continue
			}

			// merge backwards
			if min-size == p.To.Offset {
				clear.From.Offset += size
				clear.To.Offset -= size
				excise(r)
				n++
				continue
			}
		}

		// transform into clear
		p.From.Type = obj.TYPE_CONST
		p.From.Offset = size
		p.From.Reg = 0
		p.As = s390x.ACLEAR
		clear = p
		align = size
	}
	return n
}

// fuseMultiple merges memory loads and stores into load multiple and
// store multiple operations.
//
// Looks for this pattern (sequence of loads or stores):
// 	MOVD	R1, 0(R15)
//	MOVD	R2, 8(R15)
//	MOVD	R3, 16(R15)
// Replaces with:
//	STMG	R1, R3, 0(R15)
func fuseMultiple(r *gc.Flow) int {
	n := 0
	var fused *obj.Prog
	for ; r != nil; r = r.Link {
		// If there is a branch into the instruction stream then
		// we can't fuse into previous instructions.
		if gc.Uniqp(r) == nil {
			fused = nil
		}

		p := r.Prog

		isStore := isGPR(&p.From) && isBDMem(&p.To)
		isLoad := isGPR(&p.To) && isBDMem(&p.From)

		// are we a candidate?
		size := int64(0)
		switch p.As {
		default:
			fused = nil
			continue
		case obj.ANOP:
			// skip over nops
			continue
		case s390x.AMOVW, s390x.AMOVWZ:
			size = 4
			// TODO(mundaym): 32-bit load multiple is currently not supported
			// as it requires sign/zero extension.
			if !isStore {
				fused = nil
				continue
			}
		case s390x.AMOVD:
			size = 8
			if !isLoad && !isStore {
				fused = nil
				continue
			}
		}

		// If we merge two loads/stores with different source/destination Nodes
		// then we will lose a reference the second Node which means that the
		// compiler might mark the Node as unused and free its slot on the stack.
		// TODO(mundaym): allow this by adding a dummy reference to the Node.
		if fused == nil ||
			fused.From.Node != p.From.Node ||
			fused.From.Type != p.From.Type ||
			fused.To.Node != p.To.Node ||
			fused.To.Type != p.To.Type {
			fused = p
			continue
		}

		// check two addresses
		ca := func(a, b *obj.Addr, offset int64) bool {
			return a.Reg == b.Reg && a.Offset+offset == b.Offset &&
				a.Sym == b.Sym && a.Name == b.Name
		}

		switch fused.As {
		default:
			fused = p
		case s390x.AMOVW, s390x.AMOVWZ:
			if size == 4 && fused.From.Reg+1 == p.From.Reg && ca(&fused.To, &p.To, 4) {
				fused.As = s390x.ASTMY
				fused.Reg = p.From.Reg
				excise(r)
				n++
			} else {
				fused = p
			}
		case s390x.AMOVD:
			if size == 8 && fused.From.Reg+1 == p.From.Reg && ca(&fused.To, &p.To, 8) {
				fused.As = s390x.ASTMG
				fused.Reg = p.From.Reg
				excise(r)
				n++
			} else if size == 8 && fused.To.Reg+1 == p.To.Reg && ca(&fused.From, &p.From, 8) {
				fused.As = s390x.ALMG
				fused.Reg = fused.To.Reg
				fused.To.Reg = p.To.Reg
				excise(r)
				n++
			} else {
				fused = p
			}
		case s390x.ASTMG, s390x.ASTMY:
			if (fused.As == s390x.ASTMY && size != 4) ||
				(fused.As == s390x.ASTMG && size != 8) {
				fused = p
				continue
			}
			offset := size * int64(fused.Reg-fused.From.Reg+1)
			if fused.Reg+1 == p.From.Reg && ca(&fused.To, &p.To, offset) {
				fused.Reg = p.From.Reg
				excise(r)
				n++
			} else {
				fused = p
			}
		case s390x.ALMG:
			offset := 8 * int64(fused.To.Reg-fused.Reg+1)
			if size == 8 && fused.To.Reg+1 == p.To.Reg && ca(&fused.From, &p.From, offset) {
				fused.To.Reg = p.To.Reg
				excise(r)
				n++
			} else {
				fused = p
			}
		}
	}
	return n
}

// simplifyOps looks for side-effect free ops that can be removed or
// replaced with moves.
//
// For example:
// 	XOR $0, R1 => NOP
//	ADD $0, R1, R2 => MOVD R1, R2
func simplifyOps(r *gc.Flow) int {
	n := 0
	for ; r != nil; r = r.Link {
		p := r.Prog

		// if the target is R0 then this is a required NOP
		if isGPR(&p.To) && p.To.Reg == s390x.REGZERO {
			continue
		}

		switch p.As {
		case s390x.AADD, s390x.ASUB,
			s390x.AOR, s390x.AXOR,
			s390x.ASLW, s390x.ASRW, s390x.ASRAW,
			s390x.ASLD, s390x.ASRD, s390x.ASRAD,
			s390x.ARLL, s390x.ARLLG:
			if isZero(&p.From) && isGPR(&p.To) {
				if p.Reg == 0 || p.Reg == p.To.Reg {
					excise(r)
					n++
				} else {
					p.As = s390x.AMOVD
					p.From.Type = obj.TYPE_REG
					p.From.Reg = p.Reg
					p.Reg = 0
				}
			}
		case s390x.AMULLW, s390x.AAND:
			if isZero(&p.From) && isGPR(&p.To) {
				p.As = s390x.AMOVD
				p.From.Type = obj.TYPE_REG
				p.From.Reg = s390x.REGZERO
				p.Reg = 0
			}
		}
	}
	return n
}

// fuseOpMoves looks for moves following 2-operand operations and trys to merge them into
// a 3-operand operation.
//
// For example:
//	ADD R1, R2
//	MOVD R2, R3
// might become
//	ADD R1, R2, R3
func fuseOpMoves(r *gc.Flow) int {
	n := 0
	for ; r != nil; r = r.Link {
		p := r.Prog
		switch p.As {
		case s390x.AADD:
		case s390x.ASUB:
			if isConst(&p.From) && int64(int16(p.From.Offset)) != p.From.Offset {
				continue
			}
		case s390x.ASLW,
			s390x.ASRW,
			s390x.ASRAW,
			s390x.ASLD,
			s390x.ASRD,
			s390x.ASRAD,
			s390x.ARLL,
			s390x.ARLLG:
			// ok - p.From will be a reg or a constant
		case s390x.AOR,
			s390x.AORN,
			s390x.AAND,
			s390x.AANDN,
			s390x.ANAND,
			s390x.ANOR,
			s390x.AXOR,
			s390x.AMULLW,
			s390x.AMULLD:
			if isConst(&p.From) {
				// these instructions can either use 3 register form
				// or have an immediate but not both
				continue
			}
		default:
			continue
		}

		if p.Reg != 0 && p.Reg != p.To.Reg {
			continue
		}

		var move *gc.Flow
		rr := gc.Uniqs(r)
		for {
			if rr == nil || gc.Uniqp(rr) == nil || rr == r {
				break
			}
			pp := rr.Prog
			switch copyu(pp, &p.To, nil) {
			case _None:
				rr = gc.Uniqs(rr)
				continue
			case _Read:
				if move == nil && pp.As == s390x.AMOVD && isGPR(&pp.From) && isGPR(&pp.To) {
					move = rr
					rr = gc.Uniqs(rr)
					continue
				}
			case _Write:
				if move == nil {
					// dead code
					excise(r)
					n++
				} else {
					for prev := gc.Uniqp(move); prev != r; prev = gc.Uniqp(prev) {
						if copyu(prev.Prog, &move.Prog.To, nil) != 0 {
							move = nil
							break
						}
					}
					if move == nil {
						break
					}
					p.Reg, p.To.Reg = p.To.Reg, move.Prog.To.Reg
					excise(move)
					n++

					// clean up
					if p.From.Reg == p.To.Reg && isCommutative(p.As) {
						p.From.Reg, p.Reg = p.Reg, 0
					}
					if p.To.Reg == p.Reg {
						p.Reg = 0
					}
					// we could try again if p has become a 2-operand op
					// but in testing nothing extra was extracted
				}
			}
			break
		}
	}
	return n
}

// isCommutative returns true if the order of input operands
// does not affect the result. For example:
//	x + y == y + x so ADD is commutative
//	x ^ y == y ^ x so XOR is commutative
func isCommutative(as obj.As) bool {
	switch as {
	case s390x.AADD,
		s390x.AOR,
		s390x.AAND,
		s390x.AXOR,
		s390x.AMULLW,
		s390x.AMULLD:
		return true
	}
	return false
}

// applyCast applies the cast implied by the given move
// instruction to v and returns the result.
func applyCast(cast obj.As, v int64) int64 {
	switch cast {
	case s390x.AMOVWZ:
		return int64(uint32(v))
	case s390x.AMOVHZ:
		return int64(uint16(v))
	case s390x.AMOVBZ:
		return int64(uint8(v))
	case s390x.AMOVW:
		return int64(int32(v))
	case s390x.AMOVH:
		return int64(int16(v))
	case s390x.AMOVB:
		return int64(int8(v))
	}
	return v
}

// constantPropagation removes redundant constant copies.
func constantPropagation(r *gc.Flow) int {
	n := 0
	// find MOV $con,R followed by
	// another MOV $con,R without
	// setting R in the interim
	for ; r != nil; r = r.Link {
		p := r.Prog
		if isMove(p) {
			if !isReg(&p.To) {
				continue
			}
			if !isConst(&p.From) {
				continue
			}
		} else {
			continue
		}

		rr := r
		for {
			rr = gc.Uniqs(rr)
			if rr == nil || rr == r {
				break
			}
			if gc.Uniqp(rr) == nil {
				break
			}

			pp := rr.Prog
			t := copyu(pp, &p.To, nil)
			switch t {
			case _None:
				continue
			case _Read:
				if !isGPR(&pp.From) || !isMove(pp) {
					continue
				}
				if p.From.Type == obj.TYPE_CONST {
					v := applyCast(p.As, p.From.Offset)
					if isGPR(&pp.To) {
						if int64(int32(v)) == v || ((v>>32)<<32) == v {
							pp.From.Reg = 0
							pp.From.Offset = v
							pp.From.Type = obj.TYPE_CONST
							n++
						}
					} else if int64(int16(v)) == v {
						pp.From.Reg = 0
						pp.From.Offset = v
						pp.From.Type = obj.TYPE_CONST
						n++
					}
				}
				continue
			case _Write:
				if p.As != pp.As || p.From.Type != pp.From.Type {
					break
				}
				if p.From.Type == obj.TYPE_CONST && p.From.Offset == pp.From.Offset {
					excise(rr)
					n++
					continue
				} else if p.From.Type == obj.TYPE_FCONST {
					if p.From.Val.(float64) == pp.From.Val.(float64) {
						excise(rr)
						n++
						continue
					}
				}
			}
			break
		}
	}
	return n
}

// copyPropagation tries to eliminate register-to-register moves.
func copyPropagation(r *gc.Flow) int {
	n := 0
	for ; r != nil; r = r.Link {
		p := r.Prog
		if isMove(p) && isReg(&p.To) {
			// Convert uses to $0 to uses of R0 and
			// propagate R0
			if isGPR(&p.To) && isZero(&p.From) {
				p.From.Type = obj.TYPE_REG
				p.From.Reg = s390x.REGZERO
			}

			// Try to eliminate reg->reg moves
			if isGPR(&p.From) || isFPR(&p.From) {
				if copyprop(r) || (subprop(r) && copyprop(r)) {
					excise(r)
					n++
				}
			}
		}
	}
	return n
}

// loadPipelining pushes any load from memory as early as possible.
func loadPipelining(r *gc.Flow) int {
	for ; r != nil; r = r.Link {
		p := r.Prog
		if isLoad(p) {
			pushback(r)
		}
	}
	return 0
}

// fuseCompareBranch finds comparisons followed by a branch and converts
// them into a compare-and-branch instruction (which avoid setting the
// condition code).
func fuseCompareBranch(r *gc.Flow) int {
	n := 0
	for ; r != nil; r = r.Link {
		p := r.Prog
		r1 := gc.Uniqs(r)
		if r1 == nil {
			continue
		}
		p1 := r1.Prog

		var ins obj.As
		switch p.As {
		case s390x.ACMP:
			switch p1.As {
			case s390x.ABCL, s390x.ABC:
				continue
			case s390x.ABEQ:
				ins = s390x.ACMPBEQ
			case s390x.ABGE:
				ins = s390x.ACMPBGE
			case s390x.ABGT:
				ins = s390x.ACMPBGT
			case s390x.ABLE:
				ins = s390x.ACMPBLE
			case s390x.ABLT:
				ins = s390x.ACMPBLT
			case s390x.ABNE:
				ins = s390x.ACMPBNE
			default:
				continue
			}

		case s390x.ACMPU:
			switch p1.As {
			case s390x.ABCL, s390x.ABC:
				continue
			case s390x.ABEQ:
				ins = s390x.ACMPUBEQ
			case s390x.ABGE:
				ins = s390x.ACMPUBGE
			case s390x.ABGT:
				ins = s390x.ACMPUBGT
			case s390x.ABLE:
				ins = s390x.ACMPUBLE
			case s390x.ABLT:
				ins = s390x.ACMPUBLT
			case s390x.ABNE:
				ins = s390x.ACMPUBNE
			default:
				continue
			}

		case s390x.ACMPW, s390x.ACMPWU:
			continue

		default:
			continue
		}

		if gc.Debug['P'] != 0 && gc.Debug['v'] != 0 {
			fmt.Printf("cnb %v; %v  ", p, p1)
		}

		if p1.To.Sym != nil {
			continue
		}

		if p.To.Type == obj.TYPE_REG {
			p1.As = ins
			p1.From = p.From
			p1.Reg = p.To.Reg
			p1.From3 = nil
		} else if p.To.Type == obj.TYPE_CONST {
			switch p.As {
			case s390x.ACMP, s390x.ACMPW:
				if (p.To.Offset < -(1 << 7)) || (p.To.Offset >= ((1 << 7) - 1)) {
					continue
				}
			case s390x.ACMPU, s390x.ACMPWU:
				if p.To.Offset >= (1 << 8) {
					continue
				}
			default:
			}
			p1.As = ins
			p1.From = p.From
			p1.Reg = 0
			p1.From3 = new(obj.Addr)
			*(p1.From3) = p.To
		} else {
			continue
		}

		if gc.Debug['P'] != 0 && gc.Debug['v'] != 0 {
			fmt.Printf("%v\n", p1)
		}
		excise(r)
		n++
	}
	return n
}

// deadCodeElimination removes writes to registers which are written
// to again before they are next read.
func deadCodeElimination(r *gc.Flow) int {
	n := 0
	for ; r != nil; r = r.Link {
		p := r.Prog
		// Currently there are no instructions which write to multiple
		// registers in copyu. This check will need to change if there
		// ever are.
		if !(isGPR(&p.To) || isFPR(&p.To)) || copyu(p, &p.To, nil) != _Write {
			continue
		}
		for rr := gc.Uniqs(r); rr != nil; rr = gc.Uniqs(rr) {
			t := copyu(rr.Prog, &p.To, nil)
			if t == _None {
				continue
			}
			if t == _Write {
				excise(r)
				n++
			}
			break
		}
	}
	return n
}
