Home | History | Annotate | Download | only in lc3b
      1 /*
      2  * LC-3b architecture description
      3  *
      4  *  Copyright (C) 2003-2007  Peter Johnson
      5  *
      6  * Redistribution and use in source and binary forms, with or without
      7  * modification, are permitted provided that the following conditions
      8  * are met:
      9  * 1. Redistributions of source code must retain the above copyright
     10  *    notice, this list of conditions and the following disclaimer.
     11  * 2. Redistributions in binary form must reproduce the above copyright
     12  *    notice, this list of conditions and the following disclaimer in the
     13  *    documentation and/or other materials provided with the distribution.
     14  *
     15  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
     16  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     18  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
     19  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     20  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     21  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     22  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     23  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     24  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     25  * POSSIBILITY OF SUCH DAMAGE.
     26  */
     27 #include <util.h>
     28 
     29 #include <libyasm.h>
     30 
     31 #include "lc3barch.h"
     32 
     33 
     34 yasm_arch_module yasm_lc3b_LTX_arch;
     35 
     36 
     37 static /*@only@*/ yasm_arch *
     38 lc3b_create(const char *machine, const char *parser,
     39             /*@out@*/ yasm_arch_create_error *error)
     40 {
     41     yasm_arch_base *arch;
     42 
     43     *error = YASM_ARCH_CREATE_OK;
     44 
     45     if (yasm__strcasecmp(machine, "lc3b") != 0) {
     46         *error = YASM_ARCH_CREATE_BAD_MACHINE;
     47         return NULL;
     48     }
     49 
     50     if (yasm__strcasecmp(parser, "nasm") != 0) {
     51         *error = YASM_ARCH_CREATE_BAD_PARSER;
     52         return NULL;
     53     }
     54 
     55     arch = yasm_xmalloc(sizeof(yasm_arch_base));
     56     arch->module = &yasm_lc3b_LTX_arch;
     57     return (yasm_arch *)arch;
     58 }
     59 
     60 static void
     61 lc3b_destroy(/*@only@*/ yasm_arch *arch)
     62 {
     63     yasm_xfree(arch);
     64 }
     65 
     66 static const char *
     67 lc3b_get_machine(/*@unused@*/ const yasm_arch *arch)
     68 {
     69     return "lc3b";
     70 }
     71 
     72 static unsigned int
     73 lc3b_get_address_size(/*@unused@*/ const yasm_arch *arch)
     74 {
     75     return 16;
     76 }
     77 
     78 static int
     79 lc3b_set_var(yasm_arch *arch, const char *var, unsigned long val)
     80 {
     81     return 1;
     82 }
     83 
     84 static const unsigned char **
     85 lc3b_get_fill(const yasm_arch *arch)
     86 {
     87     /* NOP pattern is all 0's per LC-3b Assembler 3.50 output */
     88     static const unsigned char *fill[16] = {
     89         NULL,           /* unused */
     90         NULL,           /* 1 - illegal; all opcodes are 2 bytes long */
     91         (const unsigned char *)
     92         "\x00\x00",                     /* 4 */
     93         NULL,                           /* 3 - illegal */
     94         (const unsigned char *)
     95         "\x00\x00\x00\x00",             /* 4 */
     96         NULL,                           /* 5 - illegal */
     97         (const unsigned char *)
     98         "\x00\x00\x00\x00\x00\x00",     /* 6 */
     99         NULL,                           /* 7 - illegal */
    100         (const unsigned char *)
    101         "\x00\x00\x00\x00\x00\x00"      /* 8 */
    102         "\x00\x00",
    103         NULL,                           /* 9 - illegal */
    104         (const unsigned char *)
    105         "\x00\x00\x00\x00\x00\x00"      /* 10 */
    106         "\x00\x00\x00\x00",
    107         NULL,                           /* 11 - illegal */
    108         (const unsigned char *)
    109         "\x00\x00\x00\x00\x00\x00"      /* 12 */
    110         "\x00\x00\x00\x00\x00\x00",
    111         NULL,                           /* 13 - illegal */
    112         (const unsigned char *)
    113         "\x00\x00\x00\x00\x00\x00"      /* 14 */
    114         "\x00\x00\x00\x00\x00\x00\x00\x00",
    115         NULL                            /* 15 - illegal */
    116     };
    117     return fill;
    118 }
    119 
    120 static unsigned int
    121 lc3b_get_reg_size(/*@unused@*/ yasm_arch *arch, /*@unused@*/ uintptr_t reg)
    122 {
    123     return 16;
    124 }
    125 
    126 static uintptr_t
    127 lc3b_reggroup_get_reg(/*@unused@*/ yasm_arch *arch,
    128                       /*@unused@*/ uintptr_t reggroup,
    129                       /*@unused@*/ unsigned long regindex)
    130 {
    131     return 0;
    132 }
    133 
    134 static void
    135 lc3b_reg_print(/*@unused@*/ yasm_arch *arch, uintptr_t reg, FILE *f)
    136 {
    137     fprintf(f, "r%u", (unsigned int)(reg&7));
    138 }
    139 
    140 static int
    141 lc3b_floatnum_tobytes(yasm_arch *arch, const yasm_floatnum *flt,
    142                       unsigned char *buf, size_t destsize, size_t valsize,
    143                       size_t shift, int warn)
    144 {
    145     yasm_error_set(YASM_ERROR_FLOATING_POINT,
    146                    N_("LC-3b does not support floating point"));
    147     return 1;
    148 }
    149 
    150 static yasm_effaddr *
    151 lc3b_ea_create_expr(yasm_arch *arch, yasm_expr *e)
    152 {
    153     yasm_effaddr *ea = yasm_xmalloc(sizeof(yasm_effaddr));
    154     yasm_value_initialize(&ea->disp, e, 0);
    155     ea->need_nonzero_len = 0;
    156     ea->need_disp = 1;
    157     ea->nosplit = 0;
    158     ea->strong = 0;
    159     ea->segreg = 0;
    160     ea->pc_rel = 0;
    161     ea->not_pc_rel = 0;
    162     return ea;
    163 }
    164 
    165 void
    166 yasm_lc3b__ea_destroy(/*@only@*/ yasm_effaddr *ea)
    167 {
    168     yasm_value_delete(&ea->disp);
    169     yasm_xfree(ea);
    170 }
    171 
    172 static void
    173 lc3b_ea_print(const yasm_effaddr *ea, FILE *f, int indent_level)
    174 {
    175     fprintf(f, "%*sDisp:\n", indent_level, "");
    176     yasm_value_print(&ea->disp, f, indent_level+1);
    177 }
    178 
    179 /* Define lc3b machines -- see arch.h for details */
    180 static yasm_arch_machine lc3b_machines[] = {
    181     { "LC-3b", "lc3b" },
    182     { NULL, NULL }
    183 };
    184 
    185 /* Define arch structure -- see arch.h for details */
    186 yasm_arch_module yasm_lc3b_LTX_arch = {
    187     "LC-3b",
    188     "lc3b",
    189     NULL,
    190     lc3b_create,
    191     lc3b_destroy,
    192     lc3b_get_machine,
    193     lc3b_get_address_size,
    194     lc3b_set_var,
    195     yasm_lc3b__parse_check_insnprefix,
    196     yasm_lc3b__parse_check_regtmod,
    197     lc3b_get_fill,
    198     lc3b_floatnum_tobytes,
    199     yasm_lc3b__intnum_tobytes,
    200     lc3b_get_reg_size,
    201     lc3b_reggroup_get_reg,
    202     lc3b_reg_print,
    203     NULL,       /*yasm_lc3b__segreg_print*/
    204     lc3b_ea_create_expr,
    205     yasm_lc3b__ea_destroy,
    206     lc3b_ea_print,
    207     yasm_lc3b__create_empty_insn,
    208     lc3b_machines,
    209     "lc3b",
    210     16,
    211     2
    212 };
    213