// Inferno utils/5c/peep.c
// http://code.google.com/p/inferno-os/source/browse/utils/5c/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 arm

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

var gactive uint32

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

	var r *gc.Flow
	var p *obj.Prog
	var t int
loop1:
	if gc.Debug['P'] != 0 && gc.Debug['v'] != 0 {
		gc.Dumpit("loop1", g.Start, 0)
	}

	t = 0
	for r = g.Start; r != nil; r = r.Link {
		p = r.Prog
		switch p.As {
		/*
		 * elide shift into TYPE_SHIFT operand of subsequent instruction
		 */
		//			if(shiftprop(r)) {
		//				excise(r);
		//				t++;
		//				break;
		//			}
		case arm.ASLL,
			arm.ASRL,
			arm.ASRA:
			break

		case arm.AMOVB,
			arm.AMOVH,
			arm.AMOVW,
			arm.AMOVF,
			arm.AMOVD:
			if regtyp(&p.From) {
				if p.From.Type == p.To.Type && isfloatreg(&p.From) == isfloatreg(&p.To) {
					if p.Scond == arm.C_SCOND_NONE {
						if copyprop(g, r) {
							excise(r)
							t++
							break
						}

						if subprop(r) && copyprop(g, r) {
							excise(r)
							t++
							break
						}
					}
				}
			}

		case arm.AMOVHS,
			arm.AMOVHU,
			arm.AMOVBS,
			arm.AMOVBU:
			if p.From.Type == obj.TYPE_REG {
				if shortprop(r) {
					t++
				}
			}
		}
	}

	/*
		if(p->scond == C_SCOND_NONE)
		if(regtyp(&p->to))
		if(isdconst(&p->from)) {
			constprop(&p->from, &p->to, r->s1);
		}
		break;
	*/
	if t != 0 {
		goto loop1
	}

	for r := (*gc.Flow)(g.Start); r != nil; r = r.Link {
		p = r.Prog
		switch p.As {
		/*
		 * EOR -1,x,y => MVN x,y
		 */
		case arm.AEOR:
			if isdconst(&p.From) && p.From.Offset == -1 {
				p.As = arm.AMVN
				p.From.Type = obj.TYPE_REG
				if p.Reg != 0 {
					p.From.Reg = p.Reg
				} else {
					p.From.Reg = p.To.Reg
				}
				p.Reg = 0
			}
		}
	}

	for r := (*gc.Flow)(g.Start); r != nil; r = r.Link {
		p = r.Prog
		switch p.As {
		case arm.AMOVW,
			arm.AMOVB,
			arm.AMOVBS,
			arm.AMOVBU:
			if p.From.Type == obj.TYPE_MEM && p.From.Offset == 0 {
				xtramodes(g, r, &p.From)
			} else if p.To.Type == obj.TYPE_MEM && p.To.Offset == 0 {
				xtramodes(g, r, &p.To)
			} else {
				continue
			}
		}
	}

	//		case ACMP:
	//			/*
	//			 * elide CMP $0,x if calculation of x can set condition codes
	//			 */
	//			if(isdconst(&p->from) || p->from.offset != 0)
	//				continue;
	//			r2 = r->s1;
	//			if(r2 == nil)
	//				continue;
	//			t = r2->prog->as;
	//			switch(t) {
	//			default:
	//				continue;
	//			case ABEQ:
	//			case ABNE:
	//			case ABMI:
	//			case ABPL:
	//				break;
	//			case ABGE:
	//				t = ABPL;
	//				break;
	//			case ABLT:
	//				t = ABMI;
	//				break;
	//			case ABHI:
	//				t = ABNE;
	//				break;
	//			case ABLS:
	//				t = ABEQ;
	//				break;
	//			}
	//			r1 = r;
	//			do
	//				r1 = uniqp(r1);
	//			while (r1 != nil && r1->prog->as == ANOP);
	//			if(r1 == nil)
	//				continue;
	//			p1 = r1->prog;
	//			if(p1->to.type != TYPE_REG)
	//				continue;
	//			if(p1->to.reg != p->reg)
	//			if(!(p1->as == AMOVW && p1->from.type == TYPE_REG && p1->from.reg == p->reg))
	//				continue;
	//
	//			switch(p1->as) {
	//			default:
	//				continue;
	//			case AMOVW:
	//				if(p1->from.type != TYPE_REG)
	//					continue;
	//			case AAND:
	//			case AEOR:
	//			case AORR:
	//			case ABIC:
	//			case AMVN:
	//			case ASUB:
	//			case ARSB:
	//			case AADD:
	//			case AADC:
	//			case ASBC:
	//			case ARSC:
	//				break;
	//			}
	//			p1->scond |= C_SBIT;
	//			r2->prog->as = t;
	//			excise(r);
	//			continue;

	//	predicate(g);

	gc.Flowend(g)
}

func regtyp(a *obj.Addr) bool {
	return a.Type == obj.TYPE_REG && (arm.REG_R0 <= a.Reg && a.Reg <= arm.REG_R15 || arm.REG_F0 <= a.Reg && a.Reg <= arm.REG_F15)
}

/*
 * the idea is to substitute
 * one register for another
 * from one MOV to another
 *	MOV	a, R0
 *	ADD	b, R0	/ no use of R1
 *	MOV	R0, R1
 * would be converted to
 *	MOV	a, R1
 *	ADD	b, R1
 *	MOV	R1, R0
 * hopefully, then the former or latter MOV
 * will be eliminated by copy propagation.
 */
func subprop(r0 *gc.Flow) bool {
	p := (*obj.Prog)(r0.Prog)
	v1 := (*obj.Addr)(&p.From)
	if !regtyp(v1) {
		return false
	}
	v2 := (*obj.Addr)(&p.To)
	if !regtyp(v2) {
		return false
	}
	for r := gc.Uniqp(r0); r != nil; r = gc.Uniqp(r) {
		if gc.Uniqs(r) == nil {
			break
		}
		p = r.Prog
		if p.As == obj.AVARDEF || p.As == obj.AVARKILL {
			continue
		}
		if p.Info.Flags&gc.Call != 0 {
			return false
		}

		// TODO(rsc): Whatever invalidated the info should have done this call.
		proginfo(p)

		if (p.Info.Flags&gc.CanRegRead != 0) && p.To.Type == obj.TYPE_REG {
			p.Info.Flags |= gc.RegRead
			p.Info.Flags &^= (gc.CanRegRead | gc.RightRead)
			p.Reg = p.To.Reg
		}

		switch p.As {
		case arm.AMULLU,
			arm.AMULA,
			arm.AMVN:
			return false
		}

		if p.Info.Flags&(gc.RightRead|gc.RightWrite) == gc.RightWrite {
			if p.To.Type == v1.Type {
				if p.To.Reg == v1.Reg {
					if p.Scond == arm.C_SCOND_NONE {
						copysub(&p.To, v1, v2, 1)
						if gc.Debug['P'] != 0 {
							fmt.Printf("gotit: %v->%v\n%v", gc.Ctxt.Dconv(v1), gc.Ctxt.Dconv(v2), r.Prog)
							if p.From.Type == v2.Type {
								fmt.Printf(" excise")
							}
							fmt.Printf("\n")
						}

						for r = gc.Uniqs(r); r != r0; r = gc.Uniqs(r) {
							p = r.Prog
							copysub(&p.From, v1, v2, 1)
							copysub1(p, v1, v2, 1)
							copysub(&p.To, v1, v2, 1)
							if gc.Debug['P'] != 0 {
								fmt.Printf("%v\n", r.Prog)
							}
						}

						t := int(int(v1.Reg))
						v1.Reg = v2.Reg
						v2.Reg = int16(t)
						if gc.Debug['P'] != 0 {
							fmt.Printf("%v last\n", r.Prog)
						}
						return true
					}
				}
			}
		}

		if copyau(&p.From, v2) || copyau1(p, v2) || copyau(&p.To, v2) {
			break
		}
		if copysub(&p.From, v1, v2, 0) != 0 || copysub1(p, v1, v2, 0) != 0 || copysub(&p.To, v1, v2, 0) != 0 {
			break
		}
	}

	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	F=0
 *	(use v2	s/v2/v1/)*
 *	set v1	F=1
 *	set v2	return success
 */
func copyprop(g *gc.Graph, r0 *gc.Flow) bool {
	p := (*obj.Prog)(r0.Prog)
	v1 := (*obj.Addr)(&p.From)
	v2 := (*obj.Addr)(&p.To)
	if copyas(v1, v2) {
		return true
	}
	gactive++
	return copy1(v1, v2, r0.S1, 0)
}

func copy1(v1 *obj.Addr, v2 *obj.Addr, r *gc.Flow, f int) bool {
	if uint32(r.Active) == gactive {
		if gc.Debug['P'] != 0 {
			fmt.Printf("act set; return 1\n")
		}
		return true
	}

	r.Active = int32(gactive)
	if gc.Debug['P'] != 0 {
		fmt.Printf("copy %v->%v f=%d\n", gc.Ctxt.Dconv(v1), gc.Ctxt.Dconv(v2), f)
	}
	var t int
	var p *obj.Prog
	for ; r != nil; r = r.S1 {
		p = r.Prog
		if gc.Debug['P'] != 0 {
			fmt.Printf("%v", p)
		}
		if f == 0 && gc.Uniqp(r) == nil {
			f = 1
			if gc.Debug['P'] != 0 {
				fmt.Printf("; merge; f=%d", f)
			}
		}

		t = copyu(p, v2, nil)
		switch t {
		case 2: /* rar, can't split */
			if gc.Debug['P'] != 0 {
				fmt.Printf("; %vrar; return 0\n", gc.Ctxt.Dconv(v2))
			}
			return false

		case 3: /* set */
			if gc.Debug['P'] != 0 {
				fmt.Printf("; %vset; return 1\n", gc.Ctxt.Dconv(v2))
			}
			return true

		case 1, /* used, substitute */
			4: /* use and set */
			if f != 0 {
				if gc.Debug['P'] == 0 {
					return false
				}
				if t == 4 {
					fmt.Printf("; %vused+set and f=%d; return 0\n", gc.Ctxt.Dconv(v2), f)
				} else {
					fmt.Printf("; %vused and f=%d; return 0\n", gc.Ctxt.Dconv(v2), f)
				}
				return false
			}

			if copyu(p, v2, v1) != 0 {
				if gc.Debug['P'] != 0 {
					fmt.Printf("; sub fail; return 0\n")
				}
				return false
			}

			if gc.Debug['P'] != 0 {
				fmt.Printf("; sub%v/%v", gc.Ctxt.Dconv(v2), gc.Ctxt.Dconv(v1))
			}
			if t == 4 {
				if gc.Debug['P'] != 0 {
					fmt.Printf("; %vused+set; return 1\n", gc.Ctxt.Dconv(v2))
				}
				return true
			}
		}

		if f == 0 {
			t = copyu(p, v1, nil)
			if f == 0 && (t == 2 || t == 3 || t == 4) {
				f = 1
				if gc.Debug['P'] != 0 {
					fmt.Printf("; %vset and !f; f=%d", gc.Ctxt.Dconv(v1), f)
				}
			}
		}

		if gc.Debug['P'] != 0 {
			fmt.Printf("\n")
		}
		if r.S2 != nil {
			if !copy1(v1, v2, r.S2, f) {
				return false
			}
		}
	}

	return true
}

// UNUSED
/*
 * The idea is to remove redundant constants.
 *	$c1->v1
 *	($c1->v2 s/$c1/v1)*
 *	set v1  return
 * The v1->v2 should be eliminated by copy propagation.
 */
func constprop(c1 *obj.Addr, v1 *obj.Addr, r *gc.Flow) {
	if gc.Debug['P'] != 0 {
		fmt.Printf("constprop %v->%v\n", gc.Ctxt.Dconv(c1), gc.Ctxt.Dconv(v1))
	}
	var p *obj.Prog
	for ; r != nil; r = r.S1 {
		p = r.Prog
		if gc.Debug['P'] != 0 {
			fmt.Printf("%v", p)
		}
		if gc.Uniqp(r) == nil {
			if gc.Debug['P'] != 0 {
				fmt.Printf("; merge; return\n")
			}
			return
		}

		if p.As == arm.AMOVW && copyas(&p.From, c1) {
			if gc.Debug['P'] != 0 {
				fmt.Printf("; sub%v/%v", gc.Ctxt.Dconv(&p.From), gc.Ctxt.Dconv(v1))
			}
			p.From = *v1
		} else if copyu(p, v1, nil) > 1 {
			if gc.Debug['P'] != 0 {
				fmt.Printf("; %vset; return\n", gc.Ctxt.Dconv(v1))
			}
			return
		}

		if gc.Debug['P'] != 0 {
			fmt.Printf("\n")
		}
		if r.S2 != nil {
			constprop(c1, v1, r.S2)
		}
	}
}

/*
 * shortprop eliminates redundant zero/sign extensions.
 *
 *   MOVBS x, R
 *   <no use R>
 *   MOVBS R, R'
 *
 * changed to
 *
 *   MOVBS x, R
 *   ...
 *   MOVB  R, R' (compiled to mov)
 *
 * MOVBS above can be a MOVBS, MOVBU, MOVHS or MOVHU.
 */
func shortprop(r *gc.Flow) bool {
	p := (*obj.Prog)(r.Prog)
	r1 := (*gc.Flow)(findpre(r, &p.From))
	if r1 == nil {
		return false
	}

	p1 := (*obj.Prog)(r1.Prog)
	if p1.As == p.As {
		// Two consecutive extensions.
		goto gotit
	}

	if p1.As == arm.AMOVW && isdconst(&p1.From) && p1.From.Offset >= 0 && p1.From.Offset < 128 {
		// Loaded an immediate.
		goto gotit
	}

	return false

gotit:
	if gc.Debug['P'] != 0 {
		fmt.Printf("shortprop\n%v\n%v", p1, p)
	}
	switch p.As {
	case arm.AMOVBS,
		arm.AMOVBU:
		p.As = arm.AMOVB

	case arm.AMOVHS,
		arm.AMOVHU:
		p.As = arm.AMOVH
	}

	if gc.Debug['P'] != 0 {
		fmt.Printf(" => %v\n", obj.Aconv(int(p.As)))
	}
	return true
}

// UNUSED
/*
 * ASLL x,y,w
 * .. (not use w, not set x y w)
 * AXXX w,a,b (a != w)
 * .. (not use w)
 * (set w)
 * ----------- changed to
 * ..
 * AXXX (x<<y),a,b
 * ..
 */
func shiftprop(r *gc.Flow) bool {
	p := (*obj.Prog)(r.Prog)
	if p.To.Type != obj.TYPE_REG {
		if gc.Debug['P'] != 0 {
			fmt.Printf("\tBOTCH: result not reg; FAILURE\n")
		}
		return false
	}

	n := int(int(p.To.Reg))
	a := obj.Addr(obj.Addr{})
	if p.Reg != 0 && p.Reg != p.To.Reg {
		a.Type = obj.TYPE_REG
		a.Reg = p.Reg
	}

	if gc.Debug['P'] != 0 {
		fmt.Printf("shiftprop\n%v", p)
	}
	r1 := (*gc.Flow)(r)
	var p1 *obj.Prog
	for {
		/* find first use of shift result; abort if shift operands or result are changed */
		r1 = gc.Uniqs(r1)

		if r1 == nil {
			if gc.Debug['P'] != 0 {
				fmt.Printf("\tbranch; FAILURE\n")
			}
			return false
		}

		if gc.Uniqp(r1) == nil {
			if gc.Debug['P'] != 0 {
				fmt.Printf("\tmerge; FAILURE\n")
			}
			return false
		}

		p1 = r1.Prog
		if gc.Debug['P'] != 0 {
			fmt.Printf("\n%v", p1)
		}
		switch copyu(p1, &p.To, nil) {
		case 0: /* not used or set */
			if (p.From.Type == obj.TYPE_REG && copyu(p1, &p.From, nil) > 1) || (a.Type == obj.TYPE_REG && copyu(p1, &a, nil) > 1) {
				if gc.Debug['P'] != 0 {
					fmt.Printf("\targs modified; FAILURE\n")
				}
				return false
			}

			continue
		case 3: /* set, not used */
			{
				if gc.Debug['P'] != 0 {
					fmt.Printf("\tBOTCH: noref; FAILURE\n")
				}
				return false
			}
		}

		break
	}

	/* check whether substitution can be done */
	switch p1.As {
	default:
		if gc.Debug['P'] != 0 {
			fmt.Printf("\tnon-dpi; FAILURE\n")
		}
		return false

	case arm.AAND,
		arm.AEOR,
		arm.AADD,
		arm.AADC,
		arm.AORR,
		arm.ASUB,
		arm.ASBC,
		arm.ARSB,
		arm.ARSC:
		if int(p1.Reg) == n || (p1.Reg == 0 && p1.To.Type == obj.TYPE_REG && int(p1.To.Reg) == n) {
			if p1.From.Type != obj.TYPE_REG {
				if gc.Debug['P'] != 0 {
					fmt.Printf("\tcan't swap; FAILURE\n")
				}
				return false
			}

			p1.Reg = p1.From.Reg
			p1.From.Reg = int16(n)
			switch p1.As {
			case arm.ASUB:
				p1.As = arm.ARSB

			case arm.ARSB:
				p1.As = arm.ASUB

			case arm.ASBC:
				p1.As = arm.ARSC

			case arm.ARSC:
				p1.As = arm.ASBC
			}

			if gc.Debug['P'] != 0 {
				fmt.Printf("\t=>%v", p1)
			}
		}
		fallthrough

	case arm.ABIC,
		arm.ATST,
		arm.ACMP,
		arm.ACMN:
		if int(p1.Reg) == n {
			if gc.Debug['P'] != 0 {
				fmt.Printf("\tcan't swap; FAILURE\n")
			}
			return false
		}

		if p1.Reg == 0 && int(p1.To.Reg) == n {
			if gc.Debug['P'] != 0 {
				fmt.Printf("\tshift result used twice; FAILURE\n")
			}
			return false
		}

		//	case AMVN:
		if p1.From.Type == obj.TYPE_SHIFT {
			if gc.Debug['P'] != 0 {
				fmt.Printf("\tshift result used in shift; FAILURE\n")
			}
			return false
		}

		if p1.From.Type != obj.TYPE_REG || int(p1.From.Reg) != n {
			if gc.Debug['P'] != 0 {
				fmt.Printf("\tBOTCH: where is it used?; FAILURE\n")
			}
			return false
		}
	}

	/* check whether shift result is used subsequently */
	p2 := (*obj.Prog)(p1)

	if int(p1.To.Reg) != n {
		var p1 *obj.Prog
		for {
			r1 = gc.Uniqs(r1)
			if r1 == nil {
				if gc.Debug['P'] != 0 {
					fmt.Printf("\tinconclusive; FAILURE\n")
				}
				return false
			}

			p1 = r1.Prog
			if gc.Debug['P'] != 0 {
				fmt.Printf("\n%v", p1)
			}
			switch copyu(p1, &p.To, nil) {
			case 0: /* not used or set */
				continue

			case 3: /* set, not used */
				break

			default: /* used */
				if gc.Debug['P'] != 0 {
					fmt.Printf("\treused; FAILURE\n")
				}
				return false
			}

			break
		}
	}

	/* make the substitution */
	p2.From.Reg = 0

	o := int(int(p.Reg))
	if o == 0 {
		o = int(p.To.Reg)
	}
	o &= 15

	switch p.From.Type {
	case obj.TYPE_CONST:
		o |= int((p.From.Offset & 0x1f) << 7)

	case obj.TYPE_REG:
		o |= 1<<4 | (int(p.From.Reg)&15)<<8
	}

	switch p.As {
	case arm.ASLL:
		o |= 0 << 5

	case arm.ASRL:
		o |= 1 << 5

	case arm.ASRA:
		o |= 2 << 5
	}

	p2.From = obj.Addr{}
	p2.From.Type = obj.TYPE_SHIFT
	p2.From.Offset = int64(o)
	if gc.Debug['P'] != 0 {
		fmt.Printf("\t=>%v\tSUCCEED\n", p2)
	}
	return true
}

/*
 * findpre returns the last instruction mentioning v
 * before r. It must be a set, and there must be
 * a unique path from that instruction to r.
 */
func findpre(r *gc.Flow, v *obj.Addr) *gc.Flow {
	var r1 *gc.Flow

	for r1 = gc.Uniqp(r); r1 != nil; r, r1 = r1, gc.Uniqp(r1) {
		if gc.Uniqs(r1) != r {
			return nil
		}
		switch copyu(r1.Prog, v, nil) {
		case 1, /* used */
			2: /* read-alter-rewrite */
			return nil

		case 3, /* set */
			4: /* set and used */
			return r1
		}
	}

	return nil
}

/*
 * findinc finds ADD instructions with a constant
 * argument which falls within the immed_12 range.
 */
func findinc(r *gc.Flow, r2 *gc.Flow, v *obj.Addr) *gc.Flow {
	var r1 *gc.Flow
	var p *obj.Prog

	for r1 = gc.Uniqs(r); r1 != nil && r1 != r2; r, r1 = r1, gc.Uniqs(r1) {
		if gc.Uniqp(r1) != r {
			return nil
		}
		switch copyu(r1.Prog, v, nil) {
		case 0: /* not touched */
			continue

		case 4: /* set and used */
			p = r1.Prog

			if p.As == arm.AADD {
				if isdconst(&p.From) {
					if p.From.Offset > -4096 && p.From.Offset < 4096 {
						return r1
					}
				}
			}
			fallthrough

		default:
			return nil
		}
	}

	return nil
}

func nochange(r *gc.Flow, r2 *gc.Flow, p *obj.Prog) bool {
	if r == r2 {
		return true
	}
	n := int(0)
	var a [3]obj.Addr
	if p.Reg != 0 && p.Reg != p.To.Reg {
		a[n].Type = obj.TYPE_REG
		a[n].Reg = p.Reg
		n++
	}

	switch p.From.Type {
	case obj.TYPE_SHIFT:
		a[n].Type = obj.TYPE_REG
		a[n].Reg = int16(arm.REG_R0 + (p.From.Offset & 0xf))
		n++
		fallthrough

	case obj.TYPE_REG:
		a[n].Type = obj.TYPE_REG
		a[n].Reg = p.From.Reg
		n++
	}

	if n == 0 {
		return true
	}
	var i int
	for ; r != nil && r != r2; r = gc.Uniqs(r) {
		p = r.Prog
		for i = 0; i < n; i++ {
			if copyu(p, &a[i], nil) > 1 {
				return false
			}
		}
	}

	return true
}

func findu1(r *gc.Flow, v *obj.Addr) bool {
	for ; r != nil; r = r.S1 {
		if r.Active != 0 {
			return false
		}
		r.Active = 1
		switch copyu(r.Prog, v, nil) {
		case 1, /* used */
			2, /* read-alter-rewrite */
			4: /* set and used */
			return true

		case 3: /* set */
			return false
		}

		if r.S2 != nil {
			if findu1(r.S2, v) {
				return true
			}
		}
	}

	return false
}

func finduse(g *gc.Graph, r *gc.Flow, v *obj.Addr) bool {
	for r1 := (*gc.Flow)(g.Start); r1 != nil; r1 = r1.Link {
		r1.Active = 0
	}
	return findu1(r, v)
}

/*
 * xtramodes enables the ARM post increment and
 * shift offset addressing modes to transform
 *   MOVW   0(R3),R1
 *   ADD    $4,R3,R3
 * into
 *   MOVW.P 4(R3),R1
 * and
 *   ADD    R0,R1
 *   MOVBU  0(R1),R0
 * into
 *   MOVBU  R0<<0(R1),R0
 */
func xtramodes(g *gc.Graph, r *gc.Flow, a *obj.Addr) bool {
	p := (*obj.Prog)(r.Prog)
	v := obj.Addr(*a)
	v.Type = obj.TYPE_REG
	r1 := (*gc.Flow)(findpre(r, &v))
	if r1 != nil {
		p1 := r1.Prog
		if p1.To.Type == obj.TYPE_REG && p1.To.Reg == v.Reg {
			switch p1.As {
			case arm.AADD:
				if p1.Scond&arm.C_SBIT != 0 {
					// avoid altering ADD.S/ADC sequences.
					break
				}

				if p1.From.Type == obj.TYPE_REG || (p1.From.Type == obj.TYPE_SHIFT && p1.From.Offset&(1<<4) == 0 && ((p.As != arm.AMOVB && p.As != arm.AMOVBS) || (a == &p.From && p1.From.Offset&^0xf == 0))) || ((p1.From.Type == obj.TYPE_ADDR || p1.From.Type == obj.TYPE_CONST) && p1.From.Offset > -4096 && p1.From.Offset < 4096) {
					if nochange(gc.Uniqs(r1), r, p1) {
						if a != &p.From || v.Reg != p.To.Reg {
							if finduse(g, r.S1, &v) {
								if p1.Reg == 0 || p1.Reg == v.Reg {
									/* pre-indexing */
									p.Scond |= arm.C_WBIT
								} else {
									return false
								}
							}
						}

						switch p1.From.Type {
						/* register offset */
						case obj.TYPE_REG:
							if gc.Nacl {
								return false
							}
							*a = obj.Addr{}
							a.Type = obj.TYPE_SHIFT
							a.Offset = int64(p1.From.Reg) & 15

							/* scaled register offset */
						case obj.TYPE_SHIFT:
							if gc.Nacl {
								return false
							}
							*a = obj.Addr{}
							a.Type = obj.TYPE_SHIFT
							fallthrough

							/* immediate offset */
						case obj.TYPE_CONST,
							obj.TYPE_ADDR:
							a.Offset = p1.From.Offset
						}

						if p1.Reg != 0 {
							a.Reg = p1.Reg
						}
						excise(r1)
						return true
					}
				}

			case arm.AMOVW:
				if p1.From.Type == obj.TYPE_REG {
					r2 := (*gc.Flow)(findinc(r1, r, &p1.From))
					if r2 != nil {
						var r3 *gc.Flow
						for r3 = gc.Uniqs(r2); r3.Prog.As == obj.ANOP; r3 = gc.Uniqs(r3) {
						}
						if r3 == r {
							/* post-indexing */
							p1 := r2.Prog

							a.Reg = p1.To.Reg
							a.Offset = p1.From.Offset
							p.Scond |= arm.C_PBIT
							if !finduse(g, r, &r1.Prog.To) {
								excise(r1)
							}
							excise(r2)
							return true
						}
					}
				}
			}
		}
	}

	if a != &p.From || a.Reg != p.To.Reg {
		r1 := (*gc.Flow)(findinc(r, nil, &v))
		if r1 != nil {
			/* post-indexing */
			p1 := r1.Prog

			a.Offset = p1.From.Offset
			p.Scond |= arm.C_PBIT
			excise(r1)
			return true
		}
	}

	return false
}

/*
 * return
 * 1 if v only used (and substitute),
 * 2 if read-alter-rewrite
 * 3 if set
 * 4 if set and used
 * 0 otherwise (not touched)
 */
func copyu(p *obj.Prog, v *obj.Addr, s *obj.Addr) int {
	switch p.As {
	default:
		fmt.Printf("copyu: can't find %v\n", obj.Aconv(int(p.As)))
		return 2

	case arm.AMOVM:
		if v.Type != obj.TYPE_REG {
			return 0
		}
		if p.From.Type == obj.TYPE_CONST { /* read reglist, read/rar */
			if s != nil {
				if p.From.Offset&(1<<uint(v.Reg)) != 0 {
					return 1
				}
				if copysub(&p.To, v, s, 1) != 0 {
					return 1
				}
				return 0
			}

			if copyau(&p.To, v) {
				if p.Scond&arm.C_WBIT != 0 {
					return 2
				}
				return 1
			}

			if p.From.Offset&(1<<uint(v.Reg)) != 0 {
				return 1 /* read/rar, write reglist */
			}
		} else {
			if s != nil {
				if p.To.Offset&(1<<uint(v.Reg)) != 0 {
					return 1
				}
				if copysub(&p.From, v, s, 1) != 0 {
					return 1
				}
				return 0
			}

			if copyau(&p.From, v) {
				if p.Scond&arm.C_WBIT != 0 {
					return 2
				}
				if p.To.Offset&(1<<uint(v.Reg)) != 0 {
					return 4
				}
				return 1
			}

			if p.To.Offset&(1<<uint(v.Reg)) != 0 {
				return 3
			}
		}

		return 0

	case obj.ANOP, /* read,, write */
		arm.ASQRTD,
		arm.AMOVW,
		arm.AMOVF,
		arm.AMOVD,
		arm.AMOVH,
		arm.AMOVHS,
		arm.AMOVHU,
		arm.AMOVB,
		arm.AMOVBS,
		arm.AMOVBU,
		arm.AMOVFW,
		arm.AMOVWF,
		arm.AMOVDW,
		arm.AMOVWD,
		arm.AMOVFD,
		arm.AMOVDF:
		if p.Scond&(arm.C_WBIT|arm.C_PBIT) != 0 {
			if v.Type == obj.TYPE_REG {
				if p.From.Type == obj.TYPE_MEM || p.From.Type == obj.TYPE_SHIFT {
					if p.From.Reg == v.Reg {
						return 2
					}
				} else {
					if p.To.Reg == v.Reg {
						return 2
					}
				}
			}
		}

		if s != nil {
			if copysub(&p.From, v, s, 1) != 0 {
				return 1
			}
			if !copyas(&p.To, v) {
				if copysub(&p.To, v, s, 1) != 0 {
					return 1
				}
			}
			return 0
		}

		if copyas(&p.To, v) {
			if p.Scond != arm.C_SCOND_NONE {
				return 2
			}
			if copyau(&p.From, v) {
				return 4
			}
			return 3
		}

		if copyau(&p.From, v) {
			return 1
		}
		if copyau(&p.To, v) {
			return 1
		}
		return 0

	case arm.AMULLU, /* read, read, write, write */
		arm.AMULL,
		arm.AMULA,
		arm.AMVN:
		return 2

	case arm.AADD, /* read, read, write */
		arm.AADC,
		arm.ASUB,
		arm.ASBC,
		arm.ARSB,
		arm.ASLL,
		arm.ASRL,
		arm.ASRA,
		arm.AORR,
		arm.AAND,
		arm.AEOR,
		arm.AMUL,
		arm.AMULU,
		arm.ADIV,
		arm.ADIVU,
		arm.AMOD,
		arm.AMODU,
		arm.AADDF,
		arm.AADDD,
		arm.ASUBF,
		arm.ASUBD,
		arm.AMULF,
		arm.AMULD,
		arm.ADIVF,
		arm.ADIVD,
		obj.ACHECKNIL,
		/* read */
		arm.ACMPF, /* read, read, */
		arm.ACMPD,
		arm.ACMP,
		arm.ACMN,
		arm.ACASE,
		arm.ATST:
		/* read,, */
		if s != nil {
			if copysub(&p.From, v, s, 1) != 0 {
				return 1
			}
			if copysub1(p, v, s, 1) != 0 {
				return 1
			}
			if !copyas(&p.To, v) {
				if copysub(&p.To, v, s, 1) != 0 {
					return 1
				}
			}
			return 0
		}

		if copyas(&p.To, v) {
			if p.Scond != arm.C_SCOND_NONE {
				return 2
			}
			if p.Reg == 0 {
				p.Reg = p.To.Reg
			}
			if copyau(&p.From, v) {
				return 4
			}
			if copyau1(p, v) {
				return 4
			}
			return 3
		}

		if copyau(&p.From, v) {
			return 1
		}
		if copyau1(p, v) {
			return 1
		}
		if copyau(&p.To, v) {
			return 1
		}
		return 0

	case arm.ABEQ, /* read, read */
		arm.ABNE,
		arm.ABCS,
		arm.ABHS,
		arm.ABCC,
		arm.ABLO,
		arm.ABMI,
		arm.ABPL,
		arm.ABVS,
		arm.ABVC,
		arm.ABHI,
		arm.ABLS,
		arm.ABGE,
		arm.ABLT,
		arm.ABGT,
		arm.ABLE:
		if s != nil {
			if copysub(&p.From, v, s, 1) != 0 {
				return 1
			}
			return copysub1(p, v, s, 1)
		}

		if copyau(&p.From, v) {
			return 1
		}
		if copyau1(p, v) {
			return 1
		}
		return 0

	case arm.AB: /* funny */
		if s != nil {
			if copysub(&p.To, v, s, 1) != 0 {
				return 1
			}
			return 0
		}

		if copyau(&p.To, v) {
			return 1
		}
		return 0

	case obj.ARET: /* funny */
		if s != nil {
			return 1
		}
		return 3

	case arm.ABL: /* funny */
		if v.Type == obj.TYPE_REG {
			// TODO(rsc): REG_R0 and REG_F0 used to be
			// (when register numbers started at 0) exregoffset and exfregoffset,
			// which are unset entirely.
			// It's strange that this handles R0 and F0 differently from the other
			// registers. Possible failure to optimize?
			if arm.REG_R0 < v.Reg && v.Reg <= arm.REGEXT {
				return 2
			}
			if v.Reg == arm.REGARG {
				return 2
			}
			if arm.REG_F0 < v.Reg && v.Reg <= arm.FREGEXT {
				return 2
			}
		}

		if p.From.Type == obj.TYPE_REG && v.Type == obj.TYPE_REG && p.From.Reg == v.Reg {
			return 2
		}

		if s != nil {
			if copysub(&p.To, v, s, 1) != 0 {
				return 1
			}
			return 0
		}

		if copyau(&p.To, v) {
			return 4
		}
		return 3

		// R0 is zero, used by DUFFZERO, cannot be substituted.
	// R1 is ptr to memory, used and set, cannot be substituted.
	case obj.ADUFFZERO:
		if v.Type == obj.TYPE_REG {
			if v.Reg == arm.REG_R0 {
				return 1
			}
			if v.Reg == arm.REG_R0+1 {
				return 2
			}
		}

		return 0

		// R0 is scratch, set by DUFFCOPY, cannot be substituted.
	// R1, R2 areptr to src, dst, used and set, cannot be substituted.
	case obj.ADUFFCOPY:
		if v.Type == obj.TYPE_REG {
			if v.Reg == arm.REG_R0 {
				return 3
			}
			if v.Reg == arm.REG_R0+1 || v.Reg == arm.REG_R0+2 {
				return 2
			}
		}

		return 0

	case obj.ATEXT: /* funny */
		if v.Type == obj.TYPE_REG {
			if v.Reg == arm.REGARG {
				return 3
			}
		}
		return 0

	case obj.APCDATA,
		obj.AFUNCDATA,
		obj.AVARDEF,
		obj.AVARKILL:
		return 0
	}
}

/*
 * direct reference,
 * could be set/use depending on
 * semantics
 */
func copyas(a *obj.Addr, v *obj.Addr) bool {
	if regtyp(v) {
		if a.Type == v.Type {
			if a.Reg == v.Reg {
				return true
			}
		}
	} else if v.Type == obj.TYPE_CONST { /* for constprop */
		if a.Type == v.Type {
			if a.Name == v.Name {
				if a.Sym == v.Sym {
					if a.Reg == v.Reg {
						if a.Offset == v.Offset {
							return true
						}
					}
				}
			}
		}
	}

	return false
}

func sameaddr(a *obj.Addr, v *obj.Addr) bool {
	if a.Type != v.Type {
		return false
	}
	if regtyp(v) && a.Reg == v.Reg {
		return true
	}

	// TODO(rsc): Change v->type to v->name and enable.
	//if(v->type == NAME_AUTO || v->type == NAME_PARAM) {
	//	if(v->offset == a->offset)
	//		return 1;
	//}
	return false
}

/*
 * either direct or indirect
 */
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_ADDR && a.Reg != 0 {
			if a.Reg == v.Reg {
				return true
			}
		} else if a.Type == obj.TYPE_MEM {
			if a.Reg == v.Reg {
				return true
			}
		} else if a.Type == obj.TYPE_REGREG || a.Type == obj.TYPE_REGREG2 {
			if a.Reg == v.Reg {
				return true
			}
			if a.Offset == int64(v.Reg) {
				return true
			}
		} else if a.Type == obj.TYPE_SHIFT {
			if a.Offset&0xf == int64(v.Reg-arm.REG_R0) {
				return true
			}
			if (a.Offset&(1<<4) != 0) && (a.Offset>>8)&0xf == int64(v.Reg-arm.REG_R0) {
				return true
			}
		}
	}

	return false
}

/*
 * compare v to the center
 * register in p (p->reg)
 */
func copyau1(p *obj.Prog, v *obj.Addr) bool {
	if v.Type == obj.TYPE_REG && v.Reg == 0 {
		return false
	}
	return p.Reg == v.Reg
}

/*
 * substitute s for v in a
 * return failure to substitute
 */
func copysub(a *obj.Addr, v *obj.Addr, s *obj.Addr, f int) int {
	if f != 0 {
		if copyau(a, v) {
			if a.Type == obj.TYPE_SHIFT {
				if a.Offset&0xf == int64(v.Reg-arm.REG_R0) {
					a.Offset = a.Offset&^0xf | int64(s.Reg)&0xf
				}
				if (a.Offset&(1<<4) != 0) && (a.Offset>>8)&0xf == int64(v.Reg-arm.REG_R0) {
					a.Offset = a.Offset&^(0xf<<8) | (int64(s.Reg)&0xf)<<8
				}
			} else if a.Type == obj.TYPE_REGREG || a.Type == obj.TYPE_REGREG2 {
				if a.Offset == int64(v.Reg) {
					a.Offset = int64(s.Reg)
				}
				if a.Reg == v.Reg {
					a.Reg = s.Reg
				}
			} else {
				a.Reg = s.Reg
			}
		}
	}

	return 0
}

func copysub1(p1 *obj.Prog, v *obj.Addr, s *obj.Addr, f int) int {
	if f != 0 {
		if copyau1(p1, v) {
			p1.Reg = s.Reg
		}
	}
	return 0
}

var predinfo = []struct {
	opcode    int
	notopcode int
	scond     int
	notscond  int
}{
	{arm.ABEQ, arm.ABNE, 0x0, 0x1},
	{arm.ABNE, arm.ABEQ, 0x1, 0x0},
	{arm.ABCS, arm.ABCC, 0x2, 0x3},
	{arm.ABHS, arm.ABLO, 0x2, 0x3},
	{arm.ABCC, arm.ABCS, 0x3, 0x2},
	{arm.ABLO, arm.ABHS, 0x3, 0x2},
	{arm.ABMI, arm.ABPL, 0x4, 0x5},
	{arm.ABPL, arm.ABMI, 0x5, 0x4},
	{arm.ABVS, arm.ABVC, 0x6, 0x7},
	{arm.ABVC, arm.ABVS, 0x7, 0x6},
	{arm.ABHI, arm.ABLS, 0x8, 0x9},
	{arm.ABLS, arm.ABHI, 0x9, 0x8},
	{arm.ABGE, arm.ABLT, 0xA, 0xB},
	{arm.ABLT, arm.ABGE, 0xB, 0xA},
	{arm.ABGT, arm.ABLE, 0xC, 0xD},
	{arm.ABLE, arm.ABGT, 0xD, 0xC},
}

type Joininfo struct {
	start *gc.Flow
	last  *gc.Flow
	end   *gc.Flow
	len   int
}

const (
	Join = iota
	Split
	End
	Branch
	Setcond
	Toolong
)

const (
	Falsecond = iota
	Truecond
	Delbranch
	Keepbranch
)

func isbranch(p *obj.Prog) bool {
	return (arm.ABEQ <= p.As) && (p.As <= arm.ABLE)
}

func predicable(p *obj.Prog) bool {
	switch p.As {
	case obj.ANOP,
		obj.AXXX,
		obj.ADATA,
		obj.AGLOBL,
		obj.ATEXT,
		arm.AWORD,
		arm.ABCASE,
		arm.ACASE:
		return false
	}

	if isbranch(p) {
		return false
	}
	return true
}

/*
 * Depends on an analysis of the encodings performed by 5l.
 * These seem to be all of the opcodes that lead to the "S" bit
 * being set in the instruction encodings.
 *
 * C_SBIT may also have been set explicitly in p->scond.
 */
func modifiescpsr(p *obj.Prog) bool {
	switch p.As {
	case arm.AMULLU,
		arm.AMULA,
		arm.AMULU,
		arm.ADIVU,
		arm.ATEQ,
		arm.ACMN,
		arm.ATST,
		arm.ACMP,
		arm.AMUL,
		arm.ADIV,
		arm.AMOD,
		arm.AMODU,
		arm.ABL:
		return true
	}

	if p.Scond&arm.C_SBIT != 0 {
		return true
	}
	return false
}

/*
 * Find the maximal chain of instructions starting with r which could
 * be executed conditionally
 */
func joinsplit(r *gc.Flow, j *Joininfo) int {
	j.start = r
	j.last = r
	j.len = 0
	for {
		if r.P2 != nil && (r.P1 != nil || r.P2.P2link != nil) {
			j.end = r
			return Join
		}

		if r.S1 != nil && r.S2 != nil {
			j.end = r
			return Split
		}

		j.last = r
		if r.Prog.As != obj.ANOP {
			j.len++
		}
		if r.S1 == nil && r.S2 == nil {
			j.end = r.Link
			return End
		}

		if r.S2 != nil {
			j.end = r.S2
			return Branch
		}

		if modifiescpsr(r.Prog) {
			j.end = r.S1
			return Setcond
		}

		r = r.S1
		if j.len >= 4 {
			break
		}
	}

	j.end = r
	return Toolong
}

func successor(r *gc.Flow) *gc.Flow {
	if r.S1 != nil {
		return r.S1
	} else {
		return r.S2
	}
}

func applypred(rstart *gc.Flow, j *Joininfo, cond int, branch int) {
	if j.len == 0 {
		return
	}
	var pred int
	if cond == Truecond {
		pred = predinfo[rstart.Prog.As-arm.ABEQ].scond
	} else {
		pred = predinfo[rstart.Prog.As-arm.ABEQ].notscond
	}

	for r := (*gc.Flow)(j.start); ; r = successor(r) {
		if r.Prog.As == arm.AB {
			if r != j.last || branch == Delbranch {
				excise(r)
			} else {
				if cond == Truecond {
					r.Prog.As = int16(predinfo[rstart.Prog.As-arm.ABEQ].opcode)
				} else {
					r.Prog.As = int16(predinfo[rstart.Prog.As-arm.ABEQ].notopcode)
				}
			}
		} else if predicable(r.Prog) {
			r.Prog.Scond = uint8(int(r.Prog.Scond&^arm.C_SCOND) | pred)
		}
		if r.S1 != r.Link {
			r.S1 = r.Link
			r.Link.P1 = r
		}

		if r == j.last {
			break
		}
	}
}

func predicate(g *gc.Graph) {
	var t1 int
	var t2 int
	var j1 Joininfo
	var j2 Joininfo

	for r := (*gc.Flow)(g.Start); r != nil; r = r.Link {
		if isbranch(r.Prog) {
			t1 = joinsplit(r.S1, &j1)
			t2 = joinsplit(r.S2, &j2)
			if j1.last.Link != j2.start {
				continue
			}
			if j1.end == j2.end {
				if (t1 == Branch && (t2 == Join || t2 == Setcond)) || (t2 == Join && (t1 == Join || t1 == Setcond)) {
					applypred(r, &j1, Falsecond, Delbranch)
					applypred(r, &j2, Truecond, Delbranch)
					excise(r)
					continue
				}
			}

			if t1 == End || t1 == Branch {
				applypred(r, &j1, Falsecond, Keepbranch)
				excise(r)
				continue
			}
		}
	}
}

func isdconst(a *obj.Addr) bool {
	return a.Type == obj.TYPE_CONST
}

func isfloatreg(a *obj.Addr) bool {
	return arm.REG_F0 <= a.Reg && a.Reg <= arm.REG_F15
}

func stackaddr(a *obj.Addr) bool {
	return regtyp(a) && a.Reg == arm.REGSP
}

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 excise(r *gc.Flow) {
	p := (*obj.Prog)(r.Prog)
	obj.Nopout(p)
}
