• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 *
lc3b_create(const char * machine,const char * parser,yasm_arch_create_error * error)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
lc3b_destroy(yasm_arch * arch)61 lc3b_destroy(/*@only@*/ yasm_arch *arch)
62 {
63     yasm_xfree(arch);
64 }
65 
66 static const char *
lc3b_get_machine(const yasm_arch * arch)67 lc3b_get_machine(/*@unused@*/ const yasm_arch *arch)
68 {
69     return "lc3b";
70 }
71 
72 static unsigned int
lc3b_get_address_size(const yasm_arch * arch)73 lc3b_get_address_size(/*@unused@*/ const yasm_arch *arch)
74 {
75     return 16;
76 }
77 
78 static int
lc3b_set_var(yasm_arch * arch,const char * var,unsigned long val)79 lc3b_set_var(yasm_arch *arch, const char *var, unsigned long val)
80 {
81     return 1;
82 }
83 
84 static const unsigned char **
lc3b_get_fill(const yasm_arch * arch)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
lc3b_get_reg_size(yasm_arch * arch,uintptr_t reg)121 lc3b_get_reg_size(/*@unused@*/ yasm_arch *arch, /*@unused@*/ uintptr_t reg)
122 {
123     return 16;
124 }
125 
126 static uintptr_t
lc3b_reggroup_get_reg(yasm_arch * arch,uintptr_t reggroup,unsigned long regindex)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
lc3b_reg_print(yasm_arch * arch,uintptr_t reg,FILE * f)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
lc3b_floatnum_tobytes(yasm_arch * arch,const yasm_floatnum * flt,unsigned char * buf,size_t destsize,size_t valsize,size_t shift,int warn)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 *
lc3b_ea_create_expr(yasm_arch * arch,yasm_expr * e)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
yasm_lc3b__ea_destroy(yasm_effaddr * ea)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
lc3b_ea_print(const yasm_effaddr * ea,FILE * f,int indent_level)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