// cmd/9l/noop.c, cmd/9l/pass.c, cmd/9l/span.c from Vita Nuova.
//
//	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-2008 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-2008 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.

#include <u.h>
#include <libc.h>
#include <bio.h>
#include <link.h>
#include "../cmd/9l/9.out.h"
#include "../runtime/stack.h"
#include "../runtime/funcdata.h"

static Prog zprg = {
	.as = AGOK,
	.reg = NREG,
	.from = {
		.name = D_NONE,
		.type = D_NONE,
		.reg = NREG,
	},
	.from3 = {
		.name = D_NONE,
		.type = D_NONE,
		.reg = NREG,
	},
	.to = {
		.name = D_NONE,
		.type = D_NONE,
		.reg = NREG,
	},
};

static int
symtype(Addr *a)
{
	return a->name;
}

static int
isdata(Prog *p)
{
	return p->as == ADATA || p->as == AGLOBL;
}

static int
iscall(Prog *p)
{
	return p->as == ABL;
}

static int
datasize(Prog *p)
{
	return p->reg;
}

static int
textflag(Prog *p)
{
	return p->reg;
}

static void
settextflag(Prog *p, int f)
{
	p->reg = f;
}

static void
progedit(Link *ctxt, Prog *p)
{
	char literal[64];
	LSym *s;

	USED(ctxt);

	p->from.class = 0;
	p->to.class = 0;

	// Rewrite BR/BL to symbol as D_BRANCH.
	switch(p->as) {
	case ABR:
	case ABL:
	case ARETURN:
	case ADUFFZERO:
	case ADUFFCOPY:
		if(p->to.sym != nil)
			p->to.type = D_BRANCH;
		break;
	}

	// Rewrite float constants to values stored in memory.
	switch(p->as) {
	case AFMOVS:
		if(p->from.type == D_FCONST) {
			int32 i32;
			float32 f32;
			f32 = p->from.u.dval;
			memmove(&i32, &f32, 4);
			sprint(literal, "$f32.%08ux", (uint32)i32);
			s = linklookup(ctxt, literal, 0);
			s->size = 4;
			p->from.type = D_OREG;
			p->from.sym = s;
			p->from.name = D_EXTERN;
			p->from.offset = 0;
		}
		break;
	case AFMOVD:
		if(p->from.type == D_FCONST) {
			int64 i64;
			memmove(&i64, &p->from.u.dval, 8);
			sprint(literal, "$f64.%016llux", (uvlong)i64);
			s = linklookup(ctxt, literal, 0);
			s->size = 8;
			p->from.type = D_OREG;
			p->from.sym = s;
			p->from.name = D_EXTERN;
			p->from.offset = 0;
		}
		break;
	case AMOVD:
		// Put >32-bit constants in memory and load them
		if(p->from.type == D_CONST && p->from.name == D_NONE && p->from.reg == NREG && (int32)p->from.offset != p->from.offset) {
			sprint(literal, "$i64.%016llux", (uvlong)p->from.offset);
			s = linklookup(ctxt, literal, 0);
			s->size = 8;
			p->from.type = D_OREG;
			p->from.sym = s;
			p->from.name = D_EXTERN;
			p->from.offset = 0;
		}
	}

	// Rewrite SUB constants into ADD.
	switch(p->as) {
	case ASUBC:
		if(p->from.type == D_CONST) {
			p->from.offset = -p->from.offset;
			p->as = AADDC;
		}
		break;

	case ASUBCCC:
		if(p->from.type == D_CONST) {
			p->from.offset = -p->from.offset;
			p->as = AADDCCC;
		}
		break;

	case ASUB:
		if(p->from.type == D_CONST) {
			p->from.offset = -p->from.offset;
			p->as = AADD;
		}
		break;
	}
}

static Prog*	stacksplit(Link*, Prog*, int32, int);

static void
parsetextconst(vlong arg, vlong *textstksiz, vlong *textarg)
{
	*textstksiz = arg & 0xffffffffLL;
	if(*textstksiz & 0x80000000LL)
		*textstksiz = -(-*textstksiz & 0xffffffffLL);

	*textarg = (arg >> 32) & 0xffffffffLL;
	if(*textarg & 0x80000000LL)
		*textarg = 0;
	*textarg = (*textarg+7) & ~7LL;
}

static void
addstacksplit(Link *ctxt, LSym *cursym)
{
	Prog *p, *q, *p1, *p2, *q1;
	int o, mov, aoffset;
	vlong textstksiz, textarg;
	int32 autosize;

	if(ctxt->symmorestack[0] == nil) {
		ctxt->symmorestack[0] = linklookup(ctxt, "runtime.morestack", 0);
		ctxt->symmorestack[1] = linklookup(ctxt, "runtime.morestack_noctxt", 0);
		// TODO(minux): add morestack short-cuts with small fixed frame-size.
	}

	ctxt->cursym = cursym;

	if(cursym->text == nil || cursym->text->link == nil)
		return;				

	p = cursym->text;
	parsetextconst(p->to.offset, &textstksiz, &textarg);
	
	cursym->args = p->to.offset>>32;
	cursym->locals = textstksiz;

	/*
	 * find leaf subroutines
	 * strip NOPs
	 * expand RET
	 * expand BECOME pseudo
	 */

	if(ctxt->debugvlog)
		Bprint(ctxt->bso, "%5.2f noops\n", cputime());
	Bflush(ctxt->bso);

	q = nil;
	for(p = cursym->text; p != nil; p = p->link) {
		switch(p->as) {
		/* too hard, just leave alone */
		case ATEXT:
			q = p;
			p->mark |= LABEL|LEAF|SYNC;
			if(p->link)
				p->link->mark |= LABEL;
			break;

		case ANOR:
			q = p;
			if(p->to.type == D_REG)
				if(p->to.reg == REGZERO)
					p->mark |= LABEL|SYNC;
			break;

		case ALWAR:
		case ASTWCCC:
		case AECIWX:
		case AECOWX:
		case AEIEIO:
		case AICBI:
		case AISYNC:
		case ATLBIE:
		case ATLBIEL:
		case ASLBIA:
		case ASLBIE:
		case ASLBMFEE:
		case ASLBMFEV:
		case ASLBMTE:
		case ADCBF:
		case ADCBI:
		case ADCBST:
		case ADCBT:
		case ADCBTST:
		case ADCBZ:
		case ASYNC:
		case ATLBSYNC:
		case APTESYNC:
		case ATW:
		case AWORD:
		case ARFI:
		case ARFCI:
		case ARFID:
		case AHRFID:
			q = p;
			p->mark |= LABEL|SYNC;
			continue;

		case AMOVW:
		case AMOVWZ:
		case AMOVD:
			q = p;
			switch(p->from.type) {
			case D_MSR:
			case D_SPR:
			case D_FPSCR:
			case D_CREG:
			case D_DCR:
				p->mark |= LABEL|SYNC;
			}
			switch(p->to.type) {
			case D_MSR:
			case D_SPR:
			case D_FPSCR:
			case D_CREG:
			case D_DCR:
				p->mark |= LABEL|SYNC;
			}
			continue;

		case AFABS:
		case AFABSCC:
		case AFADD:
		case AFADDCC:
		case AFCTIW:
		case AFCTIWCC:
		case AFCTIWZ:
		case AFCTIWZCC:
		case AFDIV:
		case AFDIVCC:
		case AFMADD:
		case AFMADDCC:
		case AFMOVD:
		case AFMOVDU:
		/* case AFMOVDS: */
		case AFMOVS:
		case AFMOVSU:
		/* case AFMOVSD: */
		case AFMSUB:
		case AFMSUBCC:
		case AFMUL:
		case AFMULCC:
		case AFNABS:
		case AFNABSCC:
		case AFNEG:
		case AFNEGCC:
		case AFNMADD:
		case AFNMADDCC:
		case AFNMSUB:
		case AFNMSUBCC:
		case AFRSP:
		case AFRSPCC:
		case AFSUB:
		case AFSUBCC:
			q = p;
			p->mark |= FLOAT;
			continue;

		case ABL:
		case ABCL:
		case ADUFFZERO:
		case ADUFFCOPY:
			cursym->text->mark &= ~LEAF;

		case ABC:
		case ABEQ:
		case ABGE:
		case ABGT:
		case ABLE:
		case ABLT:
		case ABNE:
		case ABR:
		case ABVC:
		case ABVS:
			p->mark |= BRANCH;
			q = p;
			q1 = p->pcond;
			if(q1 != nil) {
				while(q1->as == ANOP) {
					q1 = q1->link;
					p->pcond = q1;
				}
				if(!(q1->mark & LEAF))
					q1->mark |= LABEL;
			} else
				p->mark |= LABEL;
			q1 = p->link;
			if(q1 != nil)
				q1->mark |= LABEL;
			continue;

		case AFCMPO:
		case AFCMPU:
			q = p;
			p->mark |= FCMP|FLOAT;
			continue;

		case ARETURN:
			q = p;
			if(p->link != nil)
				p->link->mark |= LABEL;
			continue;

		case ANOP:
			q1 = p->link;
			q->link = q1;		/* q is non-nop */
			q1->mark |= p->mark;
			continue;

		default:
			q = p;
			continue;
		}
	}

	autosize = 0;
	for(p = cursym->text; p != nil; p = p->link) {
		o = p->as;
		switch(o) {
		case ATEXT:
			mov = AMOVD;
			aoffset = 0;
			autosize = textstksiz + 8;
			if((p->mark & LEAF) && autosize <= 8)
				autosize = 0;
			else
				if(autosize & 4)
					autosize += 4;
			p->to.offset = (p->to.offset & (0xffffffffull<<32)) | (uint32)(autosize-8);

			if(!(p->reg & NOSPLIT))
				p = stacksplit(ctxt, p, autosize, !(cursym->text->reg&NEEDCTXT)); // emit split check

			q = p;
			if(autosize) {
				/* use MOVDU to adjust R1 when saving R31, if autosize is small */
				if(!(cursym->text->mark & LEAF) && autosize >= -BIG && autosize <= BIG) {
					mov = AMOVDU;
					aoffset = -autosize;
				} else {
					q = appendp(ctxt, p);
					q->as = AADD;
					q->lineno = p->lineno;
					q->from.type = D_CONST;
					q->from.offset = -autosize;
					q->to.type = D_REG;
					q->to.reg = REGSP;
					q->spadj = +autosize;
				}
			} else
			if(!(cursym->text->mark & LEAF)) {
				if(ctxt->debugvlog) {
					Bprint(ctxt->bso, "save suppressed in: %s\n",
						cursym->name);
					Bflush(ctxt->bso);
				}
				cursym->text->mark |= LEAF;
			}

			if(cursym->text->mark & LEAF) {
				cursym->leaf = 1;
				break;
			}

			q = appendp(ctxt, q);
			q->as = AMOVD;
			q->lineno = p->lineno;
			q->from.type = D_SPR;
			q->from.offset = D_LR;
			q->to.type = D_REG;
			q->to.reg = REGTMP;

			q = appendp(ctxt, q);
			q->as = mov;
			q->lineno = p->lineno;
			q->from.type = D_REG;
			q->from.reg = REGTMP;
			q->to.type = D_OREG;
			q->to.offset = aoffset;
			q->to.reg = REGSP;
			if(q->as == AMOVDU)
				q->spadj = -aoffset;

			if(cursym->text->reg & WRAPPER) {
				// if(g->panic != nil && g->panic->argp == FP) g->panic->argp = bottom-of-frame
				//
				//	MOVD g_panic(g), R3
				//	CMP R0, R3
				//	BEQ end
				//	MOVD panic_argp(R3), R4
				//	ADD $(autosize+8), R1, R5
				//	CMP R4, R5
				//	BNE end
				//	ADD $8, R1, R6
				//	MOVD R6, panic_argp(R3)
				// end:
				//	NOP
				//
				// The NOP is needed to give the jumps somewhere to land.
				// It is a liblink NOP, not a ppc64 NOP: it encodes to 0 instruction bytes.


				q = appendp(ctxt, q);
				q->as = AMOVD;
				q->from.type = D_OREG;
				q->from.reg = REGG;
				q->from.offset = 4*ctxt->arch->ptrsize; // G.panic
				q->to.type = D_REG;
				q->to.reg = 3;

				q = appendp(ctxt, q);
				q->as = ACMP;
				q->from.type = D_REG;
				q->from.reg = 0;
				q->to.type = D_REG;
				q->to.reg = 3;

				q = appendp(ctxt, q);
				q->as = ABEQ;
				q->to.type = D_BRANCH;
				p1 = q;

				q = appendp(ctxt, q);
				q->as = AMOVD;
				q->from.type = D_OREG;
				q->from.reg = 3;
				q->from.offset = 0; // Panic.argp
				q->to.type = D_REG;
				q->to.reg = 4;

				q = appendp(ctxt, q);
				q->as = AADD;
				q->from.type = D_CONST;
				q->from.offset = autosize+8;
				q->reg = REGSP;
				q->to.type = D_REG;
				q->to.reg = 5;

				q = appendp(ctxt, q);
				q->as = ACMP;
				q->from.type = D_REG;
				q->from.reg = 4;
				q->to.type = D_REG;
				q->to.reg = 5;

				q = appendp(ctxt, q);
				q->as = ABNE;
				q->to.type = D_BRANCH;
				p2 = q;

				q = appendp(ctxt, q);
				q->as = AADD;
				q->from.type = D_CONST;
				q->from.offset = 8;
				q->reg = REGSP;
				q->to.type = D_REG;
				q->to.reg = 6;

				q = appendp(ctxt, q);
				q->as = AMOVD;
				q->from.type = D_REG;
				q->from.reg = 6;
				q->to.type = D_OREG;
				q->to.reg = 3;
				q->to.offset = 0; // Panic.argp

				q = appendp(ctxt, q);
				q->as = ANOP;
				p1->pcond = q;
				p2->pcond = q;
			}

			break;

		case ARETURN:
			if(p->from.type == D_CONST) {
				ctxt->diag("using BECOME (%P) is not supported!", p);
				break;
			}
			if(p->to.sym) { // retjmp
				p->as = ABR;
				p->to.type = D_BRANCH;
				break;
			}
			if(cursym->text->mark & LEAF) {
				if(!autosize) {
					p->as = ABR;
					p->from = zprg.from;
					p->to.type = D_SPR;
					p->to.offset = D_LR;
					p->mark |= BRANCH;
					break;
				}

				p->as = AADD;
				p->from.type = D_CONST;
				p->from.offset = autosize;
				p->to.type = D_REG;
				p->to.reg = REGSP;
				p->spadj = -autosize;

				q = ctxt->arch->prg();
				q->as = ABR;
				q->lineno = p->lineno;
				q->to.type = D_SPR;
				q->to.offset = D_LR;
				q->mark |= BRANCH;
				q->spadj = +autosize;

				q->link = p->link;
				p->link = q;
				break;
			}

			p->as = AMOVD;
			p->from.type = D_OREG;
			p->from.offset = 0;
			p->from.reg = REGSP;
			p->to.type = D_REG;
			p->to.reg = REGTMP;

			q = ctxt->arch->prg();
			q->as = AMOVD;
			q->lineno = p->lineno;
			q->from.type = D_REG;
			q->from.reg = REGTMP;
			q->to.type = D_SPR;
			q->to.offset = D_LR;

			q->link = p->link;
			p->link = q;
			p = q;

			if(0) {
				// Debug bad returns
				q = ctxt->arch->prg();
				q->as = AMOVD;
				q->lineno = p->lineno;
				q->from.type = D_OREG;
				q->from.offset = 0;
				q->from.reg = REGTMP;
				q->to.type = D_REG;
				q->to.reg = REGTMP;

				q->link = p->link;
				p->link = q;
				p = q;
			}

			if(autosize) {
				q = ctxt->arch->prg();
				q->as = AADD;
				q->lineno = p->lineno;
				q->from.type = D_CONST;
				q->from.offset = autosize;
				q->to.type = D_REG;
				q->to.reg = REGSP;
				q->spadj = -autosize;

				q->link = p->link;
				p->link = q;
			}

			q1 = ctxt->arch->prg();
			q1->as = ABR;
			q1->lineno = p->lineno;
			q1->to.type = D_SPR;
			q1->to.offset = D_LR;
			q1->mark |= BRANCH;
			q1->spadj = +autosize;

			q1->link = q->link;
			q->link = q1;
			break;

		case AADD:
			if(p->to.type == D_REG && p->to.reg == REGSP && p->from.type == D_CONST)
				p->spadj = -p->from.offset;
			break;
		}
	}

#if 0 // instruction scheduling
	if(debug['Q'] == 0)
		return;

	curtext = nil;
	q = nil;	/* p - 1 */
	q1 = firstp;	/* top of block */
	o = 0;		/* count of instructions */
	for(p = firstp; p != nil; p = p1) {
		p1 = p->link;
		o++;
		if(p->mark & NOSCHED){
			if(q1 != p){
				sched(q1, q);
			}
			for(; p != nil; p = p->link){
				if(!(p->mark & NOSCHED))
					break;
				q = p;
			}
			p1 = p;
			q1 = p;
			o = 0;
			continue;
		}
		if(p->mark & (LABEL|SYNC)) {
			if(q1 != p)
				sched(q1, q);
			q1 = p;
			o = 1;
		}
		if(p->mark & (BRANCH|SYNC)) {
			sched(q1, p);
			q1 = p1;
			o = 0;
		}
		if(o >= NSCHED) {
			sched(q1, p);
			q1 = p1;
			o = 0;
		}
		q = p;
	}
#endif
}

static Prog*
stacksplit(Link *ctxt, Prog *p, int32 framesize, int noctxt)
{
	Prog *q, *q1;

	// MOVD	g_stackguard(g), R3
	p = appendp(ctxt, p);
	p->as = AMOVD;
	p->from.type = D_OREG;
	p->from.reg = REGG;
	p->from.offset = 2*ctxt->arch->ptrsize;	// G.stackguard0
	if(ctxt->cursym->cfunc)
		p->from.offset = 3*ctxt->arch->ptrsize;	// G.stackguard1
	p->to.type = D_REG;
	p->to.reg = 3;

	q = nil;
	if(framesize <= StackSmall) {
		// small stack: SP < stackguard
		//	CMP	stackguard, SP
		p = appendp(ctxt, p);
		p->as = ACMPU;
		p->from.type = D_REG;
		p->from.reg = 3;
		p->to.type = D_REG;
		p->to.reg = REGSP;
	} else if(framesize <= StackBig) {
		// large stack: SP-framesize < stackguard-StackSmall
		//	ADD $-framesize, SP, R4
		//	CMP stackguard, R4
		p = appendp(ctxt, p);
		p->as = AADD;
		p->from.type = D_CONST;
		p->from.offset = -framesize;
		p->reg = REGSP;
		p->to.type = D_REG;
		p->to.reg = 4;

		p = appendp(ctxt, p);
		p->as = ACMPU;
		p->from.type = D_REG;
		p->from.reg = 3;
		p->to.type = D_REG;
		p->to.reg = 4;
	} else {
		// Such a large stack we need to protect against wraparound.
		// If SP is close to zero:
		//	SP-stackguard+StackGuard <= framesize + (StackGuard-StackSmall)
		// The +StackGuard on both sides is required to keep the left side positive:
		// SP is allowed to be slightly below stackguard. See stack.h.
		//
		// Preemption sets stackguard to StackPreempt, a very large value.
		// That breaks the math above, so we have to check for that explicitly.
		//	// stackguard is R3
		//	CMP	R3, $StackPreempt
		//	BEQ	label-of-call-to-morestack
		//	ADD	$StackGuard, SP, R4
		//	SUB	R3, R4
		//	MOVD	$(framesize+(StackGuard-StackSmall)), R31
		//	CMPU	R31, R4
		p = appendp(ctxt, p);
		p->as = ACMP;
		p->from.type = D_REG;
		p->from.reg = 3;
		p->to.type = D_CONST;
		p->to.offset = StackPreempt;

		q = p = appendp(ctxt, p);
		p->as = ABEQ;
		p->to.type = D_BRANCH;

		p = appendp(ctxt, p);
		p->as = AADD;
		p->from.type = D_CONST;
		p->from.offset = StackGuard;
		p->reg = REGSP;
		p->to.type = D_REG;
		p->to.reg = 4;

		p = appendp(ctxt, p);
		p->as = ASUB;
		p->from.type = D_REG;
		p->from.reg = 3;
		p->to.type = D_REG;
		p->to.reg = 4;

		p = appendp(ctxt, p);
		p->as = AMOVD;
		p->from.type = D_CONST;
		p->from.offset = framesize + StackGuard - StackSmall;
		p->to.type = D_REG;
		p->to.reg = REGTMP;

		p = appendp(ctxt, p);
		p->as = ACMPU;
		p->from.type = D_REG;
		p->from.reg = REGTMP;
		p->to.type = D_REG;
		p->to.reg = 4;
	}

	// q1: BLT	done
	q1 = p = appendp(ctxt, p);
	p->as = ABLT;
	p->to.type = D_BRANCH;

	// MOVD	LR, R5
	p = appendp(ctxt, p);
	p->as = AMOVD;
	p->from.type = D_SPR;
	p->from.offset = D_LR;
	p->to.type = D_REG;
	p->to.reg = 5;
	if(q)
		q->pcond = p;

	// BL	runtime.morestack(SB)
	p = appendp(ctxt, p);
	p->as = ABL;
	p->to.type = D_BRANCH;
	if(ctxt->cursym->cfunc)
		p->to.sym = linklookup(ctxt, "runtime.morestackc", 0);
	else
		p->to.sym = ctxt->symmorestack[noctxt];

	// BR	start
	p = appendp(ctxt, p);
	p->as = ABR;
	p->to.type = D_BRANCH;
	p->pcond = ctxt->cursym->text->link;

	// placeholder for q1's jump target
	p = appendp(ctxt, p);
	p->as = ANOP; // zero-width place holder
	q1->pcond = p;

	return p;
}

static void xfol(Link*, Prog*, Prog**);

static void
follow(Link *ctxt, LSym *s)
{
	Prog *firstp, *lastp;

	ctxt->cursym = s;

	firstp = ctxt->arch->prg();
	lastp = firstp;
	xfol(ctxt, s->text, &lastp);
	lastp->link = nil;
	s->text = firstp->link;
}

static int
relinv(int a)
{

	switch(a) {
	case ABEQ:	return ABNE;
	case ABNE:	return ABEQ;

	case ABGE:	return ABLT;
	case ABLT:	return ABGE;

	case ABGT:	return ABLE;
	case ABLE:	return ABGT;

	case ABVC:	return ABVS;
	case ABVS:	return ABVC;
	}
	return 0;
}

static void
xfol(Link *ctxt, Prog *p, Prog **last)
{
	Prog *q, *r;
	int a, b, i;

loop:
	if(p == nil)
		return;
	a = p->as;
	if(a == ABR) {
		q = p->pcond;
		if((p->mark&NOSCHED) || q && (q->mark&NOSCHED)){
			p->mark |= FOLL;
			(*last)->link = p;
			*last = p;
			p = p->link;
			xfol(ctxt, p, last);
			p = q;
			if(p && !(p->mark & FOLL))
				goto loop;
			return;
		}
		if(q != nil) {
			p->mark |= FOLL;
			p = q;
			if(!(p->mark & FOLL))
				goto loop;
		}
	}
	if(p->mark & FOLL) {
		for(i=0,q=p; i<4; i++,q=q->link) {
			if(q == *last || (q->mark&NOSCHED))
				break;
			b = 0;		/* set */
			a = q->as;
			if(a == ANOP) {
				i--;
				continue;
			}
			if(a == ABR || a == ARETURN || a == ARFI || a == ARFCI || a == ARFID || a == AHRFID)
				goto copy;
			if(!q->pcond || (q->pcond->mark&FOLL))
				continue;
			b = relinv(a);
			if(!b)
				continue;
		copy:
			for(;;) {
				r = ctxt->arch->prg();
				*r = *p;
				if(!(r->mark&FOLL))
					print("cant happen 1\n");
				r->mark |= FOLL;
				if(p != q) {
					p = p->link;
					(*last)->link = r;
					*last = r;
					continue;
				}
				(*last)->link = r;
				*last = r;
				if(a == ABR || a == ARETURN || a == ARFI || a == ARFCI || a == ARFID || a == AHRFID)
					return;
				r->as = b;
				r->pcond = p->link;
				r->link = p->pcond;
				if(!(r->link->mark&FOLL))
					xfol(ctxt, r->link, last);
				if(!(r->pcond->mark&FOLL))
					print("cant happen 2\n");
				return;
			}
		}

		a = ABR;
		q = ctxt->arch->prg();
		q->as = a;
		q->lineno = p->lineno;
		q->to.type = D_BRANCH;
		q->to.offset = p->pc;
		q->pcond = p;
		p = q;
	}
	p->mark |= FOLL;
	(*last)->link = p;
	*last = p;
	if(a == ABR || a == ARETURN || a == ARFI || a == ARFCI || a == ARFID || a == AHRFID){
		if(p->mark & NOSCHED){
			p = p->link;
			goto loop;
		}
		return;
	}
	if(p->pcond != nil)
	if(a != ABL && p->link != nil) {
		xfol(ctxt, p->link, last);
		p = p->pcond;
		if(p == nil || (p->mark&FOLL))
			return;
		goto loop;
	}
	p = p->link;
	goto loop;
}

static Prog*
prg(void)
{
	Prog *p;

	p = emallocz(sizeof(*p));
	*p = zprg;
	return p;
}

LinkArch linkppc64 = {
	.name = "ppc64",
	.thechar = '9',
	.endian = BigEndian,

	.addstacksplit = addstacksplit,
	.assemble = span9,
	.datasize = datasize,
	.follow = follow,
	.iscall = iscall,
	.isdata = isdata,
	.prg = prg,
	.progedit = progedit,
	.settextflag = settextflag,
	.symtype = symtype,
	.textflag = textflag,

	.minlc = 4,
	.ptrsize = 8,
	.regsize = 8,

	.D_ADDR = D_ADDR,
	.D_AUTO = D_AUTO,
	.D_BRANCH = D_BRANCH,
	.D_CONST = D_CONST,
	.D_EXTERN = D_EXTERN,
	.D_FCONST = D_FCONST,
	.D_NONE = D_NONE,
	.D_PARAM = D_PARAM,
	.D_SCONST = D_SCONST,
	.D_STATIC = D_STATIC,
	.D_OREG = D_OREG,

	.ACALL = ABL,
	.ADATA = ADATA,
	.AEND = AEND,
	.AFUNCDATA = AFUNCDATA,
	.AGLOBL = AGLOBL,
	.AJMP = ABR,
	.ANOP = ANOP,
	.APCDATA = APCDATA,
	.ARET = ARETURN,
	.ATEXT = ATEXT,
	.ATYPE = ATYPE,
	.AUSEFIELD = AUSEFIELD,
};

LinkArch linkppc64le = {
	.name = "ppc64le",
	.thechar = '9',
	.endian = LittleEndian,

	.addstacksplit = addstacksplit,
	.assemble = span9,
	.datasize = datasize,
	.follow = follow,
	.iscall = iscall,
	.isdata = isdata,
	.prg = prg,
	.progedit = progedit,
	.settextflag = settextflag,
	.symtype = symtype,
	.textflag = textflag,

	.minlc = 4,
	.ptrsize = 8,
	.regsize = 8,

	.D_ADDR = D_ADDR,
	.D_AUTO = D_AUTO,
	.D_BRANCH = D_BRANCH,
	.D_CONST = D_CONST,
	.D_EXTERN = D_EXTERN,
	.D_FCONST = D_FCONST,
	.D_NONE = D_NONE,
	.D_PARAM = D_PARAM,
	.D_SCONST = D_SCONST,
	.D_STATIC = D_STATIC,
	.D_OREG = D_OREG,

	.ACALL = ABL,
	.ADATA = ADATA,
	.AEND = AEND,
	.AFUNCDATA = AFUNCDATA,
	.AGLOBL = AGLOBL,
	.AJMP = ABR,
	.ANOP = ANOP,
	.APCDATA = APCDATA,
	.ARET = ARETURN,
	.ATEXT = ATEXT,
	.ATYPE = ATYPE,
	.AUSEFIELD = AUSEFIELD,
};
