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

// Code transformations.

#include	"l.h"
#include	"../ld/lib.h"
#include	"../../pkg/runtime/stack.h"

static	Sym*	sym_div;
static	Sym*	sym_divu;
static	Sym*	sym_mod;
static	Sym*	sym_modu;
static	Sym*	symmorestack;
static	Prog*	pmorestack;

static	Prog*	stacksplit(Prog*, int32);

static void
linkcase(Prog *casep)
{
	Prog *p;

	for(p = casep; p != P; p = p->link){
		if(p->as == ABCASE) {
			for(; p != P && p->as == ABCASE; p = p->link)
				p->pcrel = casep;
			break;
		}
	}
}

void
noops(void)
{
	Prog *p, *q, *q1, *q2;
	int o;
	Sym *tlsfallback, *gmsym;

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

	if(debug['v'])
		Bprint(&bso, "%5.2f noops\n", cputime());
	Bflush(&bso);

	symmorestack = lookup("runtime.morestack", 0);
	if(symmorestack->type != STEXT) {
		diag("runtime·morestack not defined");
		errorexit();
	}
	pmorestack = symmorestack->text;
	pmorestack->reg |= NOSPLIT;

	tlsfallback = lookup("runtime.read_tls_fallback", 0);
	gmsym = S;
	if(linkmode == LinkExternal)
		gmsym = lookup("runtime.tlsgm", 0);
	q = P;
	for(cursym = textp; cursym != nil; cursym = cursym->next) {
		for(p = cursym->text; p != P; p = p->link) {
			switch(p->as) {
			case ACASE:
				if(flag_shared)
					linkcase(p);
				break;

			case ATEXT:
				p->mark |= LEAF;
				break;
	
			case ARET:
				break;
	
			case ADIV:
			case ADIVU:
			case AMOD:
			case AMODU:
				q = p;
				if(prog_div == P)
					initdiv();
				cursym->text->mark &= ~LEAF;
				continue;
	
			case ANOP:
				q1 = p->link;
				q->link = q1;		/* q is non-nop */
				if(q1 != P)
					q1->mark |= p->mark;
				continue;
	
			case ABL:
			case ABX:
				cursym->text->mark &= ~LEAF;
	
			case ABCASE:
			case AB:
	
			case ABEQ:
			case ABNE:
			case ABCS:
			case ABHS:
			case ABCC:
			case ABLO:
			case ABMI:
			case ABPL:
			case ABVS:
			case ABVC:
			case ABHI:
			case ABLS:
			case ABGE:
			case ABLT:
			case ABGT:
			case ABLE:
				q1 = p->cond;
				if(q1 != P) {
					while(q1->as == ANOP) {
						q1 = q1->link;
						p->cond = q1;
					}
				}
				break;
			case AWORD:
				// Rewrite TLS register fetch: MRC 15, 0, <reg>, C13, C0, 3
				if((p->to.offset & 0xffff0fff) == 0xee1d0f70) {
					if(HEADTYPE == Hopenbsd) {
						p->as = ARET;
					} else if(goarm < 7) {
						if(tlsfallback->type != STEXT) {
							diag("runtime·read_tls_fallback not defined");
							errorexit();
						}
						// BL runtime.read_tls_fallback(SB)
						p->as = ABL;
						p->to.type = D_BRANCH;
						p->to.sym = tlsfallback;
						p->cond = tlsfallback->text;
						p->to.offset = 0;
						cursym->text->mark &= ~LEAF;
					}
					if(linkmode == LinkExternal) {
						// runtime.tlsgm is relocated with R_ARM_TLS_LE32
						// and $runtime.tlsgm will contain the TLS offset.
						//
						// MOV $runtime.tlsgm+tlsoffset(SB), REGTMP
						// ADD REGTMP, <reg>
						//
						// In shared mode, runtime.tlsgm is relocated with
						// R_ARM_TLS_IE32 and runtime.tlsgm(SB) will point
						// to the GOT entry containing the TLS offset.
						//
						// MOV runtime.tlsgm(SB), REGTMP
						// ADD REGTMP, <reg>
						// SUB -tlsoffset, <reg>
						//
						// The SUB compensates for tlsoffset
						// used in runtime.save_gm and runtime.load_gm.
						q = p;
						p = appendp(p);
						p->as = AMOVW;
						p->scond = 14;
						p->reg = NREG;
						if(flag_shared) {
							p->from.type = D_OREG;
							p->from.offset = 0;
						} else {
							p->from.type = D_CONST;
							p->from.offset = tlsoffset;
						}
						p->from.sym = gmsym;
						p->from.name = D_EXTERN;
						p->to.type = D_REG;
						p->to.reg = REGTMP;
						p->to.offset = 0;

						p = appendp(p);
						p->as = AADD;
						p->scond = 14;
						p->reg = NREG;
						p->from.type = D_REG;
						p->from.reg = REGTMP;
						p->to.type = D_REG;
						p->to.reg = (q->to.offset & 0xf000) >> 12;
						p->to.offset = 0;

						if(flag_shared) {
							p = appendp(p);
							p->as = ASUB;
							p->scond = 14;
							p->reg = NREG;
							p->from.type = D_CONST;
							p->from.offset = -tlsoffset;
							p->to.type = D_REG;
							p->to.reg = (q->to.offset & 0xf000) >> 12;
							p->to.offset = 0;
						}
					}
				}
			}
			q = p;
		}
	}

	for(cursym = textp; cursym != nil; cursym = cursym->next) {
		for(p = cursym->text; p != P; p = p->link) {
			o = p->as;
			switch(o) {
			case ATEXT:
				autosize = p->to.offset + 4;
				if(autosize <= 4)
				if(cursym->text->mark & LEAF) {
					p->to.offset = -4;
					autosize = 0;
				}
	
				if(!autosize && !(cursym->text->mark & LEAF)) {
					if(debug['v'])
						Bprint(&bso, "save suppressed in: %s\n",
							cursym->name);
					Bflush(&bso);
					cursym->text->mark |= LEAF;
				}
				if(cursym->text->mark & LEAF) {
					cursym->leaf = 1;
					if(!autosize)
						break;
				}
	
				if(!(p->reg & NOSPLIT))
					p = stacksplit(p, autosize); // emit split check
				
				// MOVW.W		R14,$-autosize(SP)
				p = appendp(p);
				p->as = AMOVW;
				p->scond |= C_WBIT;
				p->from.type = D_REG;
				p->from.reg = REGLINK;
				p->to.type = D_OREG;
				p->to.offset = -autosize;
				p->to.reg = REGSP;
				p->spadj = autosize;
				
				if(cursym->text->reg & WRAPPER) {
					// g->panicwrap += autosize;
					// MOVW panicwrap_offset(g), R3
					// ADD $autosize, R3
					// MOVW R3 panicwrap_offset(g)
					p = appendp(p);
					p->as = AMOVW;
					p->from.type = D_OREG;
					p->from.reg = REGG;
					p->from.offset = 2*PtrSize;
					p->to.type = D_REG;
					p->to.reg = 3;
				
					p = appendp(p);
					p->as = AADD;
					p->from.type = D_CONST;
					p->from.offset = autosize;
					p->to.type = D_REG;
					p->to.reg = 3;
					
					p = appendp(p);
					p->as = AMOVW;
					p->from.type = D_REG;
					p->from.reg = 3;
					p->to.type = D_OREG;
					p->to.reg = REGG;
					p->to.offset = 2*PtrSize;
				}
				break;
	
			case ARET:
				nocache(p);
				if(cursym->text->mark & LEAF) {
					if(!autosize) {
						p->as = AB;
						p->from = zprg.from;
						if(p->to.sym) { // retjmp
							p->to.type = D_BRANCH;
							p->cond = p->to.sym->text;
						} else {
							p->to.type = D_OREG;
							p->to.offset = 0;
							p->to.reg = REGLINK;
						}
						break;
					}
				}

				if(cursym->text->reg & WRAPPER) {
					int cond;
					
					// Preserve original RET's cond, to allow RET.EQ
					// in the implementation of reflect.call.
					cond = p->scond;
					p->scond = C_SCOND_NONE;

					// g->panicwrap -= autosize;
					// MOVW panicwrap_offset(g), R3
					// SUB $autosize, R3
					// MOVW R3 panicwrap_offset(g)
					p->as = AMOVW;
					p->from.type = D_OREG;
					p->from.reg = REGG;
					p->from.offset = 2*PtrSize;
					p->to.type = D_REG;
					p->to.reg = 3;
					p = appendp(p);
				
					p->as = ASUB;
					p->from.type = D_CONST;
					p->from.offset = autosize;
					p->to.type = D_REG;
					p->to.reg = 3;
					p = appendp(p);

					p->as = AMOVW;
					p->from.type = D_REG;
					p->from.reg = 3;
					p->to.type = D_OREG;
					p->to.reg = REGG;
					p->to.offset = 2*PtrSize;
					p = appendp(p);

					p->scond = cond;
				}

				p->as = AMOVW;
				p->scond |= C_PBIT;
				p->from.type = D_OREG;
				p->from.offset = autosize;
				p->from.reg = REGSP;
				p->to.type = D_REG;
				p->to.reg = REGPC;
				// If there are instructions following
				// this ARET, they come from a branch
				// with the same stackframe, so no spadj.
				
				if(p->to.sym) { // retjmp
					p->to.reg = REGLINK;
					q2 = appendp(p);
					q2->as = AB;
					q2->to.type = D_BRANCH;
					q2->to.sym = p->to.sym;
					q2->cond = p->to.sym->text;
					p->to.sym = nil;
					p = q2;
				}
				break;
	
			case AADD:
				if(p->from.type == D_CONST && p->from.reg == NREG && p->to.type == D_REG && p->to.reg == REGSP)
					p->spadj = -p->from.offset;
				break;

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

			case ADIV:
			case ADIVU:
			case AMOD:
			case AMODU:
				if(debug['M'])
					break;
				if(p->from.type != D_REG)
					break;
				if(p->to.type != D_REG)
					break;
				q1 = p;
	
				/* MOV a,4(SP) */
				p = appendp(p);
				p->as = AMOVW;
				p->line = q1->line;
				p->from.type = D_REG;
				p->from.reg = q1->from.reg;
				p->to.type = D_OREG;
				p->to.reg = REGSP;
				p->to.offset = 4;
	
				/* MOV b,REGTMP */
				p = appendp(p);
				p->as = AMOVW;
				p->line = q1->line;
				p->from.type = D_REG;
				p->from.reg = q1->reg;
				if(q1->reg == NREG)
					p->from.reg = q1->to.reg;
				p->to.type = D_REG;
				p->to.reg = REGTMP;
				p->to.offset = 0;
	
				/* CALL appropriate */
				p = appendp(p);
				p->as = ABL;
				p->line = q1->line;
				p->to.type = D_BRANCH;
				p->cond = p;
				switch(o) {
				case ADIV:
					p->cond = prog_div;
					p->to.sym = sym_div;
					break;
				case ADIVU:
					p->cond = prog_divu;
					p->to.sym = sym_divu;
					break;
				case AMOD:
					p->cond = prog_mod;
					p->to.sym = sym_mod;
					break;
				case AMODU:
					p->cond = prog_modu;
					p->to.sym = sym_modu;
					break;
				}
	
				/* MOV REGTMP, b */
				p = appendp(p);
				p->as = AMOVW;
				p->line = q1->line;
				p->from.type = D_REG;
				p->from.reg = REGTMP;
				p->from.offset = 0;
				p->to.type = D_REG;
				p->to.reg = q1->to.reg;
	
				/* ADD $8,SP */
				p = appendp(p);
				p->as = AADD;
				p->line = q1->line;
				p->from.type = D_CONST;
				p->from.reg = NREG;
				p->from.offset = 8;
				p->reg = NREG;
				p->to.type = D_REG;
				p->to.reg = REGSP;
				p->spadj = -8;
	
				/* SUB $8,SP */
				q1->as = ASUB;
				q1->from.type = D_CONST;
				q1->from.offset = 8;
				q1->from.reg = NREG;
				q1->reg = NREG;
				q1->to.type = D_REG;
				q1->to.reg = REGSP;
				q1->spadj = 8;
	
				break;
			case AMOVW:
				if((p->scond & C_WBIT) && p->to.type == D_OREG && p->to.reg == REGSP)
					p->spadj = -p->to.offset;
				if((p->scond & C_PBIT) && p->from.type == D_OREG && p->from.reg == REGSP && p->to.reg != REGPC)
					p->spadj = -p->from.offset;
				if(p->from.type == D_CONST && p->from.reg == REGSP && p->to.type == D_REG && p->to.reg == REGSP)
					p->spadj = -p->from.offset;
				break;
			}
		}
	}
}

static Prog*
stacksplit(Prog *p, int32 framesize)
{
	int32 arg;

	// MOVW			g_stackguard(g), R1
	p = appendp(p);
	p->as = AMOVW;
	p->from.type = D_OREG;
	p->from.reg = REGG;
	p->to.type = D_REG;
	p->to.reg = 1;
	
	if(framesize <= StackSmall) {
		// small stack: SP < stackguard
		//	CMP	stackguard, SP
		p = appendp(p);
		p->as = ACMP;
		p->from.type = D_REG;
		p->from.reg = 1;
		p->reg = REGSP;
	} else if(framesize <= StackBig) {
		// large stack: SP-framesize < stackguard-StackSmall
		//	MOVW $-framesize(SP), R2
		//	CMP stackguard, R2
		p = appendp(p);
		p->as = AMOVW;
		p->from.type = D_CONST;
		p->from.reg = REGSP;
		p->from.offset = -framesize;
		p->to.type = D_REG;
		p->to.reg = 2;
		
		p = appendp(p);
		p->as = ACMP;
		p->from.type = D_REG;
		p->from.reg = 1;
		p->reg = 2;
	} 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.
		//	CMP $StackPreempt, R1
		//	MOVW.NE $StackGuard(SP), R2
		//	SUB.NE R1, R2
		//	MOVW.NE $(framesize+(StackGuard-StackSmall)), R3
		//	CMP.NE R3, R2
		p = appendp(p);
		p->as = ACMP;
		p->from.type = D_CONST;
		p->from.offset = (uint32)StackPreempt;
		p->reg = 1;

		p = appendp(p);
		p->as = AMOVW;
		p->from.type = D_CONST;
		p->from.reg = REGSP;
		p->from.offset = StackGuard;
		p->to.type = D_REG;
		p->to.reg = 2;
		p->scond = C_SCOND_NE;
		
		p = appendp(p);
		p->as = ASUB;
		p->from.type = D_REG;
		p->from.reg = 1;
		p->to.type = D_REG;
		p->to.reg = 2;
		p->scond = C_SCOND_NE;
		
		p = appendp(p);
		p->as = AMOVW;
		p->from.type = D_CONST;
		p->from.offset = framesize + (StackGuard - StackSmall);
		p->to.type = D_REG;
		p->to.reg = 3;
		p->scond = C_SCOND_NE;
		
		p = appendp(p);
		p->as = ACMP;
		p->from.type = D_REG;
		p->from.reg = 3;
		p->reg = 2;
		p->scond = C_SCOND_NE;
	}
	
	// MOVW.LS		$framesize, R1
	p = appendp(p);
	p->as = AMOVW;
	p->scond = C_SCOND_LS;
	p->from.type = D_CONST;
	p->from.offset = framesize;
	p->to.type = D_REG;
	p->to.reg = 1;

	// MOVW.LS		$args, R2
	p = appendp(p);
	p->as = AMOVW;
	p->scond = C_SCOND_LS;
	p->from.type = D_CONST;
	arg = cursym->text->to.offset2;
	if(arg == 1) // special marker for known 0
		arg = 0;
	if(arg&3)
		diag("misaligned argument size in stack split");
	p->from.offset = arg;
	p->to.type = D_REG;
	p->to.reg = 2;

	// MOVW.LS	R14, R3
	p = appendp(p);
	p->as = AMOVW;
	p->scond = C_SCOND_LS;
	p->from.type = D_REG;
	p->from.reg = REGLINK;
	p->to.type = D_REG;
	p->to.reg = 3;

	// BL.LS		runtime.morestack(SB) // modifies LR, returns with LO still asserted
	p = appendp(p);
	p->as = ABL;
	p->scond = C_SCOND_LS;
	p->to.type = D_BRANCH;
	p->to.sym = symmorestack;
	p->cond = pmorestack;
	
	// BLS	start
	p = appendp(p);
	p->as = ABLS;
	p->to.type = D_BRANCH;
	p->cond = cursym->text->link;
	
	return p;
}

static void
sigdiv(char *n)
{
	Sym *s;

	s = lookup(n, 0);
	if(s->type == STEXT)
		if(s->sig == 0)
			s->sig = SIGNINTERN;
}

void
divsig(void)
{
	sigdiv("_div");
	sigdiv("_divu");
	sigdiv("_mod");
	sigdiv("_modu");
}

void
initdiv(void)
{
	Sym *s2, *s3, *s4, *s5;

	if(prog_div != P)
		return;
	sym_div = s2 = lookup("_div", 0);
	sym_divu = s3 = lookup("_divu", 0);
	sym_mod = s4 = lookup("_mod", 0);
	sym_modu = s5 = lookup("_modu", 0);
	prog_div = s2->text;
	prog_divu = s3->text;
	prog_mod = s4->text;
	prog_modu = s5->text;
	if(prog_div == P) {
		diag("undefined: %s", s2->name);
		prog_div = cursym->text;
	}
	if(prog_divu == P) {
		diag("undefined: %s", s3->name);
		prog_divu = cursym->text;
	}
	if(prog_mod == P) {
		diag("undefined: %s", s4->name);
		prog_mod = cursym->text;
	}
	if(prog_modu == P) {
		diag("undefined: %s", s5->name);
		prog_modu = cursym->text;
	}
}

void
nocache(Prog *p)
{
	p->optab = 0;
	p->from.class = 0;
	p->to.class = 0;
}
