145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/*
245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * LC-3b bytecode utility functions
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.org/* Bytecode callback function prototypes */
3545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
3645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void lc3b_bc_insn_destroy(void *contents);
3745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void lc3b_bc_insn_print(const void *contents, FILE *f,
3845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                               int indent_level);
3945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int lc3b_bc_insn_calc_len(yasm_bytecode *bc,
4045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                                 yasm_bc_add_span_func add_span,
4145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                                 void *add_span_data);
4245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int lc3b_bc_insn_expand(yasm_bytecode *bc, int span, long old_val,
4345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                               long new_val, /*@out@*/ long *neg_thres,
4445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                               /*@out@*/ long *pos_thres);
4545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int lc3b_bc_insn_tobytes(yasm_bytecode *bc, unsigned char **bufp,
46d65182f1818d1c19e6f3866ab6e68a262fad5185hbono@chromium.org                                unsigned char *bufstart,
4745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                                void *d, yasm_output_value_func output_value,
4845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                                /*@null@*/ yasm_output_reloc_func output_reloc);
4945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
5045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/* Bytecode callback structures */
5145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
5245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic const yasm_bytecode_callback lc3b_bc_callback_insn = {
5345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    lc3b_bc_insn_destroy,
5445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    lc3b_bc_insn_print,
5545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_bc_finalize_common,
5645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    NULL,
5745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    lc3b_bc_insn_calc_len,
5845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    lc3b_bc_insn_expand,
5945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    lc3b_bc_insn_tobytes,
6045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    0
6145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org};
6245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
6345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
6445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgvoid
6545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_lc3b__bc_transform_insn(yasm_bytecode *bc, lc3b_insn *insn)
6645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
6745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_bc_transform(bc, &lc3b_bc_callback_insn, insn);
6845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
6945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
7045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void
7145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orglc3b_bc_insn_destroy(void *contents)
7245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
7345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    lc3b_insn *insn = (lc3b_insn *)contents;
7445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_value_delete(&insn->imm);
7545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_xfree(contents);
7645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
7745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
7845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic void
7945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orglc3b_bc_insn_print(const void *contents, FILE *f, int indent_level)
8045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
8145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    const lc3b_insn *insn = (const lc3b_insn *)contents;
8245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
8345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    fprintf(f, "%*s_Instruction_\n", indent_level, "");
8445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    fprintf(f, "%*sImmediate Value:", indent_level, "");
8545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (!insn->imm.abs)
8645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        fprintf(f, " (nil)\n");
8745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    else {
8845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        indent_level++;
8945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        fprintf(f, "\n");
9045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        yasm_value_print(&insn->imm, f, indent_level);
9145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        fprintf(f, "%*sType=", indent_level, "");
9245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        switch (insn->imm_type) {
9345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            case LC3B_IMM_NONE:
9445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                fprintf(f, "NONE-SHOULDN'T HAPPEN");
9545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                break;
9645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            case LC3B_IMM_4:
9745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                fprintf(f, "4-bit");
9845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                break;
9945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            case LC3B_IMM_5:
10045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                fprintf(f, "5-bit");
10145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                break;
10245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            case LC3B_IMM_6_WORD:
10345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                fprintf(f, "6-bit, word-multiple");
10445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                break;
10545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            case LC3B_IMM_6_BYTE:
10645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                fprintf(f, "6-bit, byte-multiple");
10745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                break;
10845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            case LC3B_IMM_8:
10945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                fprintf(f, "8-bit, word-multiple");
11045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                break;
11145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            case LC3B_IMM_9:
11245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                fprintf(f, "9-bit, signed, word-multiple");
11345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                break;
11445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            case LC3B_IMM_9_PC:
11545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                fprintf(f, "9-bit, signed, word-multiple, PC-relative");
11645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                break;
11745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        }
11845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        indent_level--;
11945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
12045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* FIXME
12145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    fprintf(f, "\n%*sOrigin=", indent_level, "");
12245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (insn->origin) {
12345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        fprintf(f, "\n");
12445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        yasm_symrec_print(insn->origin, f, indent_level+1);
12545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    } else
12645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        fprintf(f, "(nil)\n");
12745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    */
12845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    fprintf(f, "%*sOpcode: %04x\n", indent_level, "",
12945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            (unsigned int)insn->opcode);
13045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
13145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
13245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int
13345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orglc3b_bc_insn_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span,
13445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                      void *add_span_data)
13545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
13645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    lc3b_insn *insn = (lc3b_insn *)bc->contents;
13745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_bytecode *target_prevbc;
13845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
13945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* Fixed size instruction length */
14045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    bc->len += 2;
14145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
14245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* Only need to worry about out-of-range to PC-relative */
14345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (insn->imm_type != LC3B_IMM_9_PC)
14445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return 0;
14545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
14645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    if (insn->imm.rel
14745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        && (!yasm_symrec_get_label(insn->imm.rel, &target_prevbc)
14845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org             || target_prevbc->section != bc->section)) {
14945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        /* External or out of segment, so we can't check distance. */
15045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        return 0;
15145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
15245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
15345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* 9-bit signed, word-multiple displacement */
15445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    add_span(add_span_data, bc, 1, &insn->imm, -512+(long)bc->len,
15545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org             511+(long)bc->len);
15645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return 0;
15745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
15845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
15945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int
16045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orglc3b_bc_insn_expand(yasm_bytecode *bc, int span, long old_val, long new_val,
16145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    /*@out@*/ long *neg_thres, /*@out@*/ long *pos_thres)
16245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
16345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_error_set(YASM_ERROR_VALUE, N_("jump target out of range"));
16445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return -1;
16545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
16645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
16745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstatic int
168d65182f1818d1c19e6f3866ab6e68a262fad5185hbono@chromium.orglc3b_bc_insn_tobytes(yasm_bytecode *bc, unsigned char **bufp,
169d65182f1818d1c19e6f3866ab6e68a262fad5185hbono@chromium.org                     unsigned char *bufstart, void *d,
17045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                     yasm_output_value_func output_value,
17145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                     /*@unused@*/ yasm_output_reloc_func output_reloc)
17245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
17345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    lc3b_insn *insn = (lc3b_insn *)bc->contents;
17445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /*@only@*/ yasm_intnum *delta;
175d65182f1818d1c19e6f3866ab6e68a262fad5185hbono@chromium.org    unsigned long buf_off = (unsigned long)(*bufp - bufstart);
17645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
17745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* Output opcode */
17845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    YASM_SAVE_16_L(*bufp, insn->opcode);
17945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
18045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* Insert immediate into opcode. */
18145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    switch (insn->imm_type) {
18245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        case LC3B_IMM_NONE:
18345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            break;
18445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        case LC3B_IMM_4:
18545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            insn->imm.size = 4;
186d65182f1818d1c19e6f3866ab6e68a262fad5185hbono@chromium.org            if (output_value(&insn->imm, *bufp, 2, buf_off, bc, 1, d))
18745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                return 1;
18845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            break;
18945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        case LC3B_IMM_5:
19045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            insn->imm.size = 5;
19145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            insn->imm.sign = 1;
192d65182f1818d1c19e6f3866ab6e68a262fad5185hbono@chromium.org            if (output_value(&insn->imm, *bufp, 2, buf_off, bc, 1, d))
19345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                return 1;
19445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            break;
19545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        case LC3B_IMM_6_WORD:
19645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            insn->imm.size = 6;
197d65182f1818d1c19e6f3866ab6e68a262fad5185hbono@chromium.org            if (output_value(&insn->imm, *bufp, 2, buf_off, bc, 1, d))
19845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                return 1;
19945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            break;
20045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        case LC3B_IMM_6_BYTE:
20145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            insn->imm.size = 6;
20245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            insn->imm.sign = 1;
203d65182f1818d1c19e6f3866ab6e68a262fad5185hbono@chromium.org            if (output_value(&insn->imm, *bufp, 2, buf_off, bc, 1, d))
20445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                return 1;
20545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            break;
20645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        case LC3B_IMM_8:
20745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            insn->imm.size = 8;
208d65182f1818d1c19e6f3866ab6e68a262fad5185hbono@chromium.org            if (output_value(&insn->imm, *bufp, 2, buf_off, bc, 1, d))
20945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                return 1;
21045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            break;
21145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        case LC3B_IMM_9_PC:
21245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            /* Adjust relative displacement to end of bytecode */
21345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            delta = yasm_intnum_create_int(-1);
21445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            if (!insn->imm.abs)
21545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                insn->imm.abs = yasm_expr_create_ident(yasm_expr_int(delta),
21645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                                                       bc->line);
21745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            else
21845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                insn->imm.abs =
21945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                    yasm_expr_create(YASM_EXPR_ADD,
22045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                                     yasm_expr_expr(insn->imm.abs),
22145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                                     yasm_expr_int(delta), bc->line);
22245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
22345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            insn->imm.size = 9;
22445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            insn->imm.sign = 1;
225d65182f1818d1c19e6f3866ab6e68a262fad5185hbono@chromium.org            if (output_value(&insn->imm, *bufp, 2, buf_off, bc, 1, d))
22645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                return 1;
22745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            break;
22845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        case LC3B_IMM_9:
22945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            insn->imm.size = 9;
230d65182f1818d1c19e6f3866ab6e68a262fad5185hbono@chromium.org            if (output_value(&insn->imm, *bufp, 2, buf_off, bc, 1, d))
23145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                return 1;
23245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            break;
23345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org        default:
23445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org            yasm_internal_error(N_("Unrecognized immediate type"));
23545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    }
23645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
23745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    *bufp += 2;     /* all instructions are 2 bytes in size */
23845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return 0;
23945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
24045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org
24145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgint
24245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_lc3b__intnum_tobytes(yasm_arch *arch, const yasm_intnum *intn,
24345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                          unsigned char *buf, size_t destsize, size_t valsize,
24445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org                          int shift, const yasm_bytecode *bc, int warn)
24545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org{
24645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    /* Write value out. */
24745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    yasm_intnum_get_sized(intn, buf, destsize, valsize, shift, 0, warn);
24845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org    return 0;
24945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}
250