/*
 * 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.
 */
#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"


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);
}
