145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* 245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * LC-3b architecture description 345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Copyright (C) 2003-2007 Peter Johnson 545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Redistribution and use in source and binary forms, with or without 745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * modification, are permitted provided that the following conditions 845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * are met: 945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 1. Redistributions of source code must retain the above copyright 1045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * notice, this list of conditions and the following disclaimer. 1145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 2. Redistributions in binary form must reproduce the above copyright 1245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * notice, this list of conditions and the following disclaimer in the 1345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * documentation and/or other materials provided with the distribution. 1445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 1545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS'' 1645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 1845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE 1945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 2045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 2345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 2445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 2545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * POSSIBILITY OF SUCH DAMAGE. 2645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 2745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include <util.h> 2845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 2945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include <libyasm.h> 3045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 3145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#include "lc3barch.h" 3245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 3345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 3445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_arch_module yasm_lc3b_LTX_arch; 3545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 3645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 3745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic /*@only@*/ yasm_arch * 3845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orglc3b_create(const char *machine, const char *parser, 3945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@out@*/ yasm_arch_create_error *error) 4045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 4145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_arch_base *arch; 4245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 4345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *error = YASM_ARCH_CREATE_OK; 4445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 4545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (yasm__strcasecmp(machine, "lc3b") != 0) { 4645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *error = YASM_ARCH_CREATE_BAD_MACHINE; 4745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return NULL; 4845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 4945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 5045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org if (yasm__strcasecmp(parser, "nasm") != 0) { 5145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org *error = YASM_ARCH_CREATE_BAD_PARSER; 5245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return NULL; 5345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } 5445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 5545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org arch = yasm_xmalloc(sizeof(yasm_arch_base)); 5645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org arch->module = &yasm_lc3b_LTX_arch; 5745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return (yasm_arch *)arch; 5845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 5945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 6045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void 6145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orglc3b_destroy(/*@only@*/ yasm_arch *arch) 6245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 6345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_xfree(arch); 6445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 6545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 6645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic const char * 6745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orglc3b_get_machine(/*@unused@*/ const yasm_arch *arch) 6845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 6945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return "lc3b"; 7045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 7145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 7245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic unsigned int 7345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orglc3b_get_address_size(/*@unused@*/ const yasm_arch *arch) 7445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 7545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 16; 7645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 7745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 7845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int 7945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orglc3b_set_var(yasm_arch *arch, const char *var, unsigned long val) 8045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 8145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 1; 8245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 8345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 8445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic const unsigned char ** 8545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orglc3b_get_fill(const yasm_arch *arch) 8645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 8745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /* NOP pattern is all 0's per LC-3b Assembler 3.50 output */ 8845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org static const unsigned char *fill[16] = { 8945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org NULL, /* unused */ 9045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org NULL, /* 1 - illegal; all opcodes are 2 bytes long */ 9145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org (const unsigned char *) 9245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "\x00\x00", /* 4 */ 9345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org NULL, /* 3 - illegal */ 9445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org (const unsigned char *) 9545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "\x00\x00\x00\x00", /* 4 */ 9645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org NULL, /* 5 - illegal */ 9745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org (const unsigned char *) 9845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "\x00\x00\x00\x00\x00\x00", /* 6 */ 9945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org NULL, /* 7 - illegal */ 10045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org (const unsigned char *) 10145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "\x00\x00\x00\x00\x00\x00" /* 8 */ 10245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "\x00\x00", 10345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org NULL, /* 9 - illegal */ 10445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org (const unsigned char *) 10545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "\x00\x00\x00\x00\x00\x00" /* 10 */ 10645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "\x00\x00\x00\x00", 10745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org NULL, /* 11 - illegal */ 10845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org (const unsigned char *) 10945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "\x00\x00\x00\x00\x00\x00" /* 12 */ 11045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "\x00\x00\x00\x00\x00\x00", 11145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org NULL, /* 13 - illegal */ 11245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org (const unsigned char *) 11345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "\x00\x00\x00\x00\x00\x00" /* 14 */ 11445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "\x00\x00\x00\x00\x00\x00\x00\x00", 11545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org NULL /* 15 - illegal */ 11645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org }; 11745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return fill; 11845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 11945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 12045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic unsigned int 12145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orglc3b_get_reg_size(/*@unused@*/ yasm_arch *arch, /*@unused@*/ uintptr_t reg) 12245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 12345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 16; 12445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 12545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 12645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic uintptr_t 12745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orglc3b_reggroup_get_reg(/*@unused@*/ yasm_arch *arch, 12845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@unused@*/ uintptr_t reggroup, 12945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@unused@*/ unsigned long regindex) 13045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 13145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 0; 13245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 13345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 13445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void 13545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orglc3b_reg_print(/*@unused@*/ yasm_arch *arch, uintptr_t reg, FILE *f) 13645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 13745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(f, "r%u", (unsigned int)(reg&7)); 13845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 13945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 14045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int 14145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orglc3b_floatnum_tobytes(yasm_arch *arch, const yasm_floatnum *flt, 14245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unsigned char *buf, size_t destsize, size_t valsize, 14345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org size_t shift, int warn) 14445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 14545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_error_set(YASM_ERROR_FLOATING_POINT, 14645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org N_("LC-3b does not support floating point")); 14745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return 1; 14845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 14945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 15045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic yasm_effaddr * 15145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orglc3b_ea_create_expr(yasm_arch *arch, yasm_expr *e) 15245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 15345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_effaddr *ea = yasm_xmalloc(sizeof(yasm_effaddr)); 15445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_value_initialize(&ea->disp, e, 0); 15545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ea->need_nonzero_len = 0; 15645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ea->need_disp = 1; 15745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ea->nosplit = 0; 15845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ea->strong = 0; 15945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ea->segreg = 0; 16045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ea->pc_rel = 0; 16145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org ea->not_pc_rel = 0; 16245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org return ea; 16345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 16445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 16545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgvoid 16645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_lc3b__ea_destroy(/*@only@*/ yasm_effaddr *ea) 16745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 16845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_value_delete(&ea->disp); 16945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_xfree(ea); 17045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 17145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 17245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void 17345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orglc3b_ea_print(const yasm_effaddr *ea, FILE *f, int indent_level) 17445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{ 17545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org fprintf(f, "%*sDisp:\n", indent_level, ""); 17645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_value_print(&ea->disp, f, indent_level+1); 17745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} 17845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 17945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* Define lc3b machines -- see arch.h for details */ 18045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic yasm_arch_machine lc3b_machines[] = { 18145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { "LC-3b", "lc3b" }, 18245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org { NULL, NULL } 18345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}; 18445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 18545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* Define arch structure -- see arch.h for details */ 18645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_arch_module yasm_lc3b_LTX_arch = { 18745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "LC-3b", 18845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "lc3b", 18945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org NULL, 19045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org lc3b_create, 19145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org lc3b_destroy, 19245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org lc3b_get_machine, 19345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org lc3b_get_address_size, 19445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org lc3b_set_var, 19545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_lc3b__parse_check_insnprefix, 19645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_lc3b__parse_check_regtmod, 19745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org lc3b_get_fill, 19845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org lc3b_floatnum_tobytes, 19945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_lc3b__intnum_tobytes, 20045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org lc3b_get_reg_size, 20145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org lc3b_reggroup_get_reg, 20245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org lc3b_reg_print, 20345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org NULL, /*yasm_lc3b__segreg_print*/ 20445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org lc3b_ea_create_expr, 20545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_lc3b__ea_destroy, 20645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org lc3b_ea_print, 20745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_lc3b__create_empty_insn, 20845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org lc3b_machines, 20945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org "lc3b", 21045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 16, 21145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 2 21245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}; 213