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