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
34yasm_arch_module yasm_lc3b_LTX_arch;
35
36
37static /*@only@*/ yasm_arch *
38lc3b_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
60static void
61lc3b_destroy(/*@only@*/ yasm_arch *arch)
62{
63    yasm_xfree(arch);
64}
65
66static const char *
67lc3b_get_machine(/*@unused@*/ const yasm_arch *arch)
68{
69    return "lc3b";
70}
71
72static unsigned int
73lc3b_get_address_size(/*@unused@*/ const yasm_arch *arch)
74{
75    return 16;
76}
77
78static int
79lc3b_set_var(yasm_arch *arch, const char *var, unsigned long val)
80{
81    return 1;
82}
83
84static const unsigned char **
85lc3b_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
120static unsigned int
121lc3b_get_reg_size(/*@unused@*/ yasm_arch *arch, /*@unused@*/ uintptr_t reg)
122{
123    return 16;
124}
125
126static uintptr_t
127lc3b_reggroup_get_reg(/*@unused@*/ yasm_arch *arch,
128                      /*@unused@*/ uintptr_t reggroup,
129                      /*@unused@*/ unsigned long regindex)
130{
131    return 0;
132}
133
134static void
135lc3b_reg_print(/*@unused@*/ yasm_arch *arch, uintptr_t reg, FILE *f)
136{
137    fprintf(f, "r%u", (unsigned int)(reg&7));
138}
139
140static int
141lc3b_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
150static yasm_effaddr *
151lc3b_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
165void
166yasm_lc3b__ea_destroy(/*@only@*/ yasm_effaddr *ea)
167{
168    yasm_value_delete(&ea->disp);
169    yasm_xfree(ea);
170}
171
172static void
173lc3b_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 */
180static yasm_arch_machine lc3b_machines[] = {
181    { "LC-3b", "lc3b" },
182    { NULL, NULL }
183};
184
185/* Define arch structure -- see arch.h for details */
186yasm_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