// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#include <u.h>
#include <libc.h>
#include "go.h"

/*
 * architecture-independent object file output
 */

static	void	outhist(Biobuf *b);
static	void	dumpglobls(void);

void
dumpobj(void)
{
	bout = Bopen(outfile, OWRITE);
	if(bout == nil) {
		flusherrors();
		print("can't create %s: %r\n", outfile);
		errorexit();
	}

	Bprint(bout, "go object %s %s %s %s\n", getgoos(), thestring, getgoversion(), expstring());
	Bprint(bout, "  exports automatically generated from\n");
	Bprint(bout, "  %s in package \"%s\"\n", curio.infile, localpkg->name);
	dumpexport();
	Bprint(bout, "\n!\n");

	outhist(bout);

	dumpglobls();
	dumptypestructs();
	dumpdata();
	dumpfuncs();

	Bterm(bout);
}

static void
dumpglobls(void)
{
	Node *n;
	NodeList *l;

	// add globals
	for(l=externdcl; l; l=l->next) {
		n = l->n;
		if(n->op != ONAME)
			continue;

		if(n->type == T)
			fatal("external %N nil type\n", n);
		if(n->class == PFUNC)
			continue;
		if(n->sym->pkg != localpkg)
			continue;
		dowidth(n->type);

		ggloblnod(n, n->type->width);
	}
}

void
Bputname(Biobuf *b, Sym *s)
{
	Bprint(b, "%s", s->pkg->prefix);
	Bputc(b, '.');
	Bwrite(b, s->name, strlen(s->name)+1);
}

static void
outzfile(Biobuf *b, char *p)
{
	char *q, *q2;

	while(p) {
		q = utfrune(p, '/');
		if(windows) {
			q2 = utfrune(p, '\\');
			if(q2 && (!q || q2 < q))
				q = q2;
		}
		if(!q) {
			zfile(b, p, strlen(p));
			return;
		}
		if(q > p)
			zfile(b, p, q-p);
		p = q + 1;
	}
}

#define isdelim(c) (c == '/' || c == '\\')

static void
outwinname(Biobuf *b, Hist *h, char *ds, char *p)
{
	if(isdelim(p[0])) {
		// full rooted name
		zfile(b, ds, 3);	// leading "c:/"
		outzfile(b, p+1);
	} else {
		// relative name
		if(h->offset == 0 && pathname && pathname[1] == ':') {
			if(tolowerrune(ds[0]) == tolowerrune(pathname[0])) {
				// using current drive
				zfile(b, pathname, 3);	// leading "c:/"
				outzfile(b, pathname+3);
			} else {
				// using drive other then current,
				// we don't have any simple way to
				// determine current working directory
				// there, therefore will output name as is
				zfile(b, ds, 2);	// leading "c:"
			}
		}
		outzfile(b, p);
	}
}

static void
outhist(Biobuf *b)
{
	Hist *h;
	char *p, ds[] = {'c', ':', '/', 0};

	for(h = hist; h != H; h = h->link) {
		p = h->name;
		if(p) {
			if(windows) {
				// if windows variable is set, then, we know already,
				// pathname is started with windows drive specifier
				// and all '\' were replaced with '/' (see lex.c)
				if(isdelim(p[0]) && isdelim(p[1])) {
					// file name has network name in it, 
					// like \\server\share\dir\file.go
					zfile(b, "//", 2);	// leading "//"
					outzfile(b, p+2);
				} else if(p[1] == ':') {
					// file name has drive letter in it
					ds[0] = p[0];
					outwinname(b, h, ds, p+2);
				} else {
					// no drive letter in file name
					outwinname(b, h, pathname, p);
				}
			} else {
				if(p[0] == '/') {
					// full rooted name, like /home/rsc/dir/file.go
					zfile(b, "/", 1);	// leading "/"
					outzfile(b, p+1);
				} else {
					// relative name, like dir/file.go
					if(h->offset >= 0 && pathname && pathname[0] == '/') {
						zfile(b, "/", 1);	// leading "/"
						outzfile(b, pathname+1);
					}
					outzfile(b, p);
				}
			}
		
		}
		zhist(b, h->line, h->offset);
	}
}

void
ieeedtod(uint64 *ieee, double native)
{
	double fr, ho, f;
	int exp;
	uint32 h, l;
	uint64 bits;

	if(native < 0) {
		ieeedtod(ieee, -native);
		*ieee |= 1ULL<<63;
		return;
	}
	if(native == 0) {
		*ieee = 0;
		return;
	}
	fr = frexp(native, &exp);
	f = 2097152L;		/* shouldnt use fp constants here */
	fr = modf(fr*f, &ho);
	h = ho;
	h &= 0xfffffL;
	f = 65536L;
	fr = modf(fr*f, &ho);
	l = ho;
	l <<= 16;
	l |= (int32)(fr*f);
	bits = ((uint64)h<<32) | l;
	if(exp < -1021) {
		// gradual underflow
		bits |= 1LL<<52;
		bits >>= -1021 - exp;
		exp = -1022;
	}
	bits |= (uint64)(exp+1022L) << 52;
	*ieee = bits;
}

int
duint8(Sym *s, int off, uint8 v)
{
	return duintxx(s, off, v, 1);
}

int
duint16(Sym *s, int off, uint16 v)
{
	return duintxx(s, off, v, 2);
}

int
duint32(Sym *s, int off, uint32 v)
{
	return duintxx(s, off, v, 4);
}

int
duint64(Sym *s, int off, uint64 v)
{
	return duintxx(s, off, v, 8);
}

int
duintptr(Sym *s, int off, uint64 v)
{
	return duintxx(s, off, v, widthptr);
}

Sym*
stringsym(char *s, int len)
{
	static int gen;
	Sym *sym;
	int off, n, m;
	struct {
		Strlit lit;
		char buf[110];
	} tmp;
	Pkg *pkg;

	if(len > 100) {
		// huge strings are made static to avoid long names
		snprint(namebuf, sizeof(namebuf), ".gostring.%d", ++gen);
		pkg = localpkg;
	} else {
		// small strings get named by their contents,
		// so that multiple modules using the same string
		// can share it.
		tmp.lit.len = len;
		memmove(tmp.lit.s, s, len);
		tmp.lit.s[len] = '\0';
		snprint(namebuf, sizeof(namebuf), "\"%Z\"", &tmp.lit);
		pkg = gostringpkg;
	}
	sym = pkglookup(namebuf, pkg);
	
	// SymUniq flag indicates that data is generated already
	if(sym->flags & SymUniq)
		return sym;
	sym->flags |= SymUniq;
	sym->def = newname(sym);

	off = 0;
	
	// string header
	off = dsymptr(sym, off, sym, widthptr+4);
	off = duint32(sym, off, len);
	
	// string data
	for(n=0; n<len; n+=m) {
		m = 8;
		if(m > len-n)
			m = len-n;
		off = dsname(sym, off, s+n, m);
	}
	off = duint8(sym, off, 0);  // terminating NUL for runtime
	off = (off+widthptr-1)&~(widthptr-1);  // round to pointer alignment
	ggloblsym(sym, off, 1);

	return sym;	
}
