/*
 * LC-3b architecture description
 *
 *  Copyright (C) 2003-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: lc3barch.c,v 1.1.1.1 2012/03/29 17:21:01 uid42307 Exp $");

#include <libyasm.h>

#include "lc3barch.h"


yasm_arch_module yasm_lc3b_LTX_arch;


static /*@only@*/ yasm_arch *
lc3b_create(const char *machine, const char *parser,
            /*@out@*/ yasm_arch_create_error *error)
{
    yasm_arch_base *arch;

    *error = YASM_ARCH_CREATE_OK;

    if (yasm__strcasecmp(machine, "lc3b") != 0) {
        *error = YASM_ARCH_CREATE_BAD_MACHINE;
        return NULL;
    }

    if (yasm__strcasecmp(parser, "nasm") != 0) {
        *error = YASM_ARCH_CREATE_BAD_PARSER;
        return NULL;
    }

    arch = yasm_xmalloc(sizeof(yasm_arch_base));
    arch->module = &yasm_lc3b_LTX_arch;
    return (yasm_arch *)arch;
}

static void
lc3b_destroy(/*@only@*/ yasm_arch *arch)
{
    yasm_xfree(arch);
}

static const char *
lc3b_get_machine(/*@unused@*/ const yasm_arch *arch)
{
    return "lc3b";
}

static unsigned int
lc3b_get_address_size(/*@unused@*/ const yasm_arch *arch)
{
    return 16;
}

static int
lc3b_set_var(yasm_arch *arch, const char *var, unsigned long val)
{
    return 1;
}

static const unsigned char **
lc3b_get_fill(const yasm_arch *arch)
{
    /* NOP pattern is all 0's per LC-3b Assembler 3.50 output */
    static const unsigned char *fill[16] = {
        NULL,           /* unused */
        NULL,           /* 1 - illegal; all opcodes are 2 bytes long */
        (const unsigned char *)
        "\x00\x00",                     /* 4 */
        NULL,                           /* 3 - illegal */
        (const unsigned char *)
        "\x00\x00\x00\x00",             /* 4 */
        NULL,                           /* 5 - illegal */
        (const unsigned char *)
        "\x00\x00\x00\x00\x00\x00",     /* 6 */
        NULL,                           /* 7 - illegal */
        (const unsigned char *)
        "\x00\x00\x00\x00\x00\x00"      /* 8 */
        "\x00\x00",
        NULL,                           /* 9 - illegal */
        (const unsigned char *)
        "\x00\x00\x00\x00\x00\x00"      /* 10 */
        "\x00\x00\x00\x00",
        NULL,                           /* 11 - illegal */
        (const unsigned char *)
        "\x00\x00\x00\x00\x00\x00"      /* 12 */
        "\x00\x00\x00\x00\x00\x00",
        NULL,                           /* 13 - illegal */
        (const unsigned char *)
        "\x00\x00\x00\x00\x00\x00"      /* 14 */
        "\x00\x00\x00\x00\x00\x00\x00\x00",
        NULL                            /* 15 - illegal */
    };
    return fill;
}

static unsigned int
lc3b_get_reg_size(/*@unused@*/ yasm_arch *arch, /*@unused@*/ uintptr_t reg)
{
    return 16;
}

static uintptr_t
lc3b_reggroup_get_reg(/*@unused@*/ yasm_arch *arch,
                      /*@unused@*/ uintptr_t reggroup,
                      /*@unused@*/ unsigned long regindex)
{
    return 0;
}

static void
lc3b_reg_print(/*@unused@*/ yasm_arch *arch, uintptr_t reg, FILE *f)
{
    fprintf(f, "r%u", (unsigned int)(reg&7));
}

static int
lc3b_floatnum_tobytes(yasm_arch *arch, const yasm_floatnum *flt,
                      unsigned char *buf, size_t destsize, size_t valsize,
                      size_t shift, int warn)
{
    yasm_error_set(YASM_ERROR_FLOATING_POINT,
                   N_("LC-3b does not support floating point"));
    return 1;
}

static yasm_effaddr *
lc3b_ea_create_expr(yasm_arch *arch, yasm_expr *e)
{
    yasm_effaddr *ea = yasm_xmalloc(sizeof(yasm_effaddr));
    yasm_value_initialize(&ea->disp, e, 0);
    ea->need_nonzero_len = 0;
    ea->need_disp = 1;
    ea->nosplit = 0;
    ea->strong = 0;
    ea->segreg = 0;
    ea->pc_rel = 0;
    ea->not_pc_rel = 0;
    return ea;
}

void
yasm_lc3b__ea_destroy(/*@only@*/ yasm_effaddr *ea)
{
    yasm_value_delete(&ea->disp);
    yasm_xfree(ea);
}

static void
lc3b_ea_print(const yasm_effaddr *ea, FILE *f, int indent_level)
{
    fprintf(f, "%*sDisp:\n", indent_level, "");
    yasm_value_print(&ea->disp, f, indent_level+1);
}

/* Define lc3b machines -- see arch.h for details */
static yasm_arch_machine lc3b_machines[] = {
    { "LC-3b", "lc3b" },
    { NULL, NULL }
};

/* Define arch structure -- see arch.h for details */
yasm_arch_module yasm_lc3b_LTX_arch = {
    "LC-3b",
    "lc3b",
    NULL,
    lc3b_create,
    lc3b_destroy,
    lc3b_get_machine,
    lc3b_get_address_size,
    lc3b_set_var,
    yasm_lc3b__parse_check_insnprefix,
    yasm_lc3b__parse_check_regtmod,
    lc3b_get_fill,
    lc3b_floatnum_tobytes,
    yasm_lc3b__intnum_tobytes,
    lc3b_get_reg_size,
    lc3b_reggroup_get_reg,
    lc3b_reg_print,
    NULL,       /*yasm_lc3b__segreg_print*/
    lc3b_ea_create_expr,
    yasm_lc3b__ea_destroy,
    lc3b_ea_print,
    yasm_lc3b__create_empty_insn,
    lc3b_machines,
    "lc3b",
    16,
    2
};
