/*
 * Align bytecode
 *
 *  Copyright (C) 2005-2007  Peter Johnson
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */
#define YASM_LIB_INTERNAL
#include "util.h"
/*@unused@*/ RCSID("$Id$");

#include "libyasm-stdint.h"
#include "coretype.h"

#include "errwarn.h"
#include "intnum.h"
#include "expr.h"

#include "bytecode.h"

#include "bc-int.h"


typedef struct bytecode_align {
    /*@only@*/ yasm_expr *boundary;	/* alignment boundary */

    /* What to fill intervening locations with, NULL if using code_fill */
    /*@only@*/ /*@null@*/ yasm_expr *fill;

    /* Maximum number of bytes to skip, NULL if no maximum. */
    /*@only@*/ /*@null@*/ yasm_expr *maxskip;

    /* Code fill, NULL if using 0 fill */
    /*@null@*/ const unsigned char **code_fill;
} bytecode_align;

static void bc_align_destroy(void *contents);
static void bc_align_print(const void *contents, FILE *f, int indent_level);
static void bc_align_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc);
static int bc_align_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span,
			     void *add_span_data);
static int bc_align_expand(yasm_bytecode *bc, int span, long old_val,
			   long new_val, /*@out@*/ long *neg_thres,
			   /*@out@*/ long *pos_thres);
static int bc_align_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
			    yasm_output_value_func output_value,
			    /*@null@*/ yasm_output_reloc_func output_reloc);

static const yasm_bytecode_callback bc_align_callback = {
    bc_align_destroy,
    bc_align_print,
    bc_align_finalize,
    bc_align_calc_len,
    bc_align_expand,
    bc_align_tobytes,
    YASM_BC_SPECIAL_OFFSET
};


static void
bc_align_destroy(void *contents)
{
    bytecode_align *align = (bytecode_align *)contents;
    if (align->boundary)
	yasm_expr_destroy(align->boundary);
    if (align->fill)
	yasm_expr_destroy(align->fill);
    if (align->maxskip)
	yasm_expr_destroy(align->maxskip);
    yasm_xfree(contents);
}

static void
bc_align_print(const void *contents, FILE *f, int indent_level)
{
    const bytecode_align *align = (const bytecode_align *)contents;
    fprintf(f, "%*s_Align_\n", indent_level, "");
    fprintf(f, "%*sBoundary=", indent_level, "");
    yasm_expr_print(align->boundary, f);
    fprintf(f, "\n%*sFill=", indent_level, "");
    yasm_expr_print(align->fill, f);
    fprintf(f, "\n%*sMax Skip=", indent_level, "");
    yasm_expr_print(align->maxskip, f);
    fprintf(f, "\n");
}

static void
bc_align_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc)
{
    bytecode_align *align = (bytecode_align *)bc->contents;
    if (!yasm_expr_get_intnum(&align->boundary, 0))
	yasm_error_set(YASM_ERROR_NOT_CONSTANT,
		       N_("align boundary must be a constant"));
    if (align->fill && !yasm_expr_get_intnum(&align->fill, 0))
	yasm_error_set(YASM_ERROR_NOT_CONSTANT,
		       N_("align fill must be a constant"));
    if (align->maxskip && !yasm_expr_get_intnum(&align->maxskip, 0))
	yasm_error_set(YASM_ERROR_NOT_CONSTANT,
		       N_("align maximum skip must be a constant"));
}

static int
bc_align_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span,
		  void *add_span_data)
{
    long neg_thres = 0;
    long pos_thres = 0;

    if (bc_align_expand(bc, 0, 0, (long)bc->offset, &neg_thres,
			&pos_thres) < 0)
	return -1;

    return 0;
}

static int
bc_align_expand(yasm_bytecode *bc, int span, long old_val, long new_val,
		/*@out@*/ long *neg_thres, /*@out@*/ long *pos_thres)
{
    bytecode_align *align = (bytecode_align *)bc->contents;
    unsigned long end;
    unsigned long boundary =
	yasm_intnum_get_uint(yasm_expr_get_intnum(&align->boundary, 0));

    if (boundary == 0) {
	bc->len = 0;
	*pos_thres = new_val;
	return 0;
    }

    end = (unsigned long)new_val;
    if ((unsigned long)new_val & (boundary-1))
	end = ((unsigned long)new_val & ~(boundary-1)) + boundary;

    *pos_thres = (long)end;
    bc->len = end - (unsigned long)new_val;

    if (align->maxskip) {
	unsigned long maxskip =
	    yasm_intnum_get_uint(yasm_expr_get_intnum(&align->maxskip, 0));
	if (bc->len > maxskip) {
	    *pos_thres = (long)end-maxskip-1;
	    bc->len = 0;
	}
    }
    return 1;
}

static int
bc_align_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
		 yasm_output_value_func output_value,
		 /*@unused@*/ yasm_output_reloc_func output_reloc)
{
    bytecode_align *align = (bytecode_align *)bc->contents;
    unsigned long len;
    unsigned long boundary =
	yasm_intnum_get_uint(yasm_expr_get_intnum(&align->boundary, 0));

    if (boundary == 0)
	return 0;
    else {
	unsigned long end = bc->offset;
	if (bc->offset & (boundary-1))
	    end = (bc->offset & ~(boundary-1)) + boundary;
	len = end - bc->offset;
	if (len == 0)
	    return 0;
	if (align->maxskip) {
	    unsigned long maxskip =
		yasm_intnum_get_uint(yasm_expr_get_intnum(&align->maxskip, 0));
	    if (len > maxskip)
		return 0;
	}
    }

    if (align->fill) {
	unsigned long v;
	v = yasm_intnum_get_uint(yasm_expr_get_intnum(&align->fill, 0));
	memset(*bufp, (int)v, len);
	*bufp += len;
    } else if (align->code_fill) {
	unsigned long maxlen = 15;
	while (!align->code_fill[maxlen] && maxlen>0)
	    maxlen--;
	if (maxlen == 0) {
	    yasm_error_set(YASM_ERROR_GENERAL,
			   N_("could not find any code alignment size"));
	    return 1;
	}

	/* Fill with maximum code fill as much as possible */
	while (len > maxlen) {
	    memcpy(*bufp, align->code_fill[maxlen], maxlen);
	    *bufp += maxlen;
	    len -= maxlen;
	}

	if (!align->code_fill[len]) {
	    yasm_error_set(YASM_ERROR_VALUE,
			   N_("invalid alignment size %d"), len);
	    return 1;
	}
	/* Handle rest of code fill */
	memcpy(*bufp, align->code_fill[len], len);
	*bufp += len;
    } else {
	/* Just fill with 0 */
	memset(*bufp, 0, len);
	*bufp += len;
    }
    return 0;
}

yasm_bytecode *
yasm_bc_create_align(yasm_expr *boundary, yasm_expr *fill,
		     yasm_expr *maxskip, const unsigned char **code_fill,
		     unsigned long line)
{
    bytecode_align *align = yasm_xmalloc(sizeof(bytecode_align));

    align->boundary = boundary;
    align->fill = fill;
    align->maxskip = maxskip;
    align->code_fill = code_fill;

    return yasm_bc_create_common(&bc_align_callback, align, line);
}
