Beispiel #1
0
/* Negate just a single ExprItem by building a -1*ei subexpression */
static void
expr_xform_neg_item(yasm_expr *e, yasm_expr__item *ei)
{
    yasm_expr *sube = yasm_xmalloc(sizeof(yasm_expr));

    /* Build -1*ei subexpression */
    sube->op = YASM_EXPR_MUL;
    sube->line = e->line;
    sube->numterms = 2;
    sube->terms[0].type = YASM_EXPR_INT;
    sube->terms[0].data.intn = yasm_intnum_create_int(-1);
    sube->terms[1] = *ei;       /* structure copy */

    /* Replace original ExprItem with subexp */
    ei->type = YASM_EXPR_EXPR;
    ei->data.expn = sube;
}
Beispiel #2
0
static int
lc3b_bc_insn_tobytes(yasm_bytecode *bc, unsigned char **bufp,
                     unsigned char *bufstart, void *d,
                     yasm_output_value_func output_value,
                     /*@unused@*/ yasm_output_reloc_func output_reloc)
{
    lc3b_insn *insn = (lc3b_insn *)bc->contents;
    /*@only@*/ yasm_intnum *delta;
    unsigned long buf_off = (unsigned long)(*bufp - bufstart);

    /* Output opcode */
    YASM_SAVE_16_L(*bufp, insn->opcode);

    /* Insert immediate into opcode. */
    switch (insn->imm_type) {
        case LC3B_IMM_NONE:
            break;
        case LC3B_IMM_4:
            insn->imm.size = 4;
            if (output_value(&insn->imm, *bufp, 2, buf_off, bc, 1, d))
                return 1;
            break;
        case LC3B_IMM_5:
            insn->imm.size = 5;
            insn->imm.sign = 1;
            if (output_value(&insn->imm, *bufp, 2, buf_off, bc, 1, d))
                return 1;
            break;
        case LC3B_IMM_6_WORD:
            insn->imm.size = 6;
            if (output_value(&insn->imm, *bufp, 2, buf_off, bc, 1, d))
                return 1;
            break;
        case LC3B_IMM_6_BYTE:
            insn->imm.size = 6;
            insn->imm.sign = 1;
            if (output_value(&insn->imm, *bufp, 2, buf_off, bc, 1, d))
                return 1;
            break;
        case LC3B_IMM_8:
            insn->imm.size = 8;
            if (output_value(&insn->imm, *bufp, 2, buf_off, bc, 1, d))
                return 1;
            break;
        case LC3B_IMM_9_PC:
            /* Adjust relative displacement to end of bytecode */
            delta = yasm_intnum_create_int(-1);
            if (!insn->imm.abs)
                insn->imm.abs = yasm_expr_create_ident(yasm_expr_int(delta),
                                                       bc->line);
            else
                insn->imm.abs =
                    yasm_expr_create(YASM_EXPR_ADD,
                                     yasm_expr_expr(insn->imm.abs),
                                     yasm_expr_int(delta), bc->line);

            insn->imm.size = 9;
            insn->imm.sign = 1;
            if (output_value(&insn->imm, *bufp, 2, buf_off, bc, 1, d))
                return 1;
            break;
        case LC3B_IMM_9:
            insn->imm.size = 9;
            if (output_value(&insn->imm, *bufp, 2, buf_off, bc, 1, d))
                return 1;
            break;
        default:
            yasm_internal_error(N_("Unrecognized immediate type"));
    }

    *bufp += 2;     /* all instructions are 2 bytes in size */
    return 0;
}
Beispiel #3
0
/* Negates e by multiplying by -1, with distribution over lower-precedence
 * operators (eg ADD) and special handling to simplify result w/ADD, NEG, and
 * others.
 *
 * Returns a possibly reallocated e.
 */
static /*@only@*/ yasm_expr *
expr_xform_neg_helper(/*@returned@*/ /*@only@*/ yasm_expr *e)
{
    yasm_expr *ne;
    int i;

    switch (e->op) {
        case YASM_EXPR_ADD:
            /* distribute (recursively if expr) over terms */
            for (i=0; i<e->numterms; i++) {
                if (e->terms[i].type == YASM_EXPR_EXPR)
                    e->terms[i].data.expn =
                        expr_xform_neg_helper(e->terms[i].data.expn);
                else
                    expr_xform_neg_item(e, &e->terms[i]);
            }
            break;
        case YASM_EXPR_SUB:
            /* change op to ADD, and recursively negate left side (if expr) */
            e->op = YASM_EXPR_ADD;
            if (e->terms[0].type == YASM_EXPR_EXPR)
                e->terms[0].data.expn =
                    expr_xform_neg_helper(e->terms[0].data.expn);
            else
                expr_xform_neg_item(e, &e->terms[0]);
            break;
        case YASM_EXPR_NEG:
            /* Negating a negated value?  Make it an IDENT. */
            e->op = YASM_EXPR_IDENT;
            break;
        case YASM_EXPR_IDENT:
            /* Negating an ident?  Change it into a MUL w/ -1 if there's no
             * floatnums present below; if there ARE floatnums, recurse.
             */
            if (e->terms[0].type == YASM_EXPR_FLOAT)
                yasm_floatnum_calc(e->terms[0].data.flt, YASM_EXPR_NEG, NULL);
            else if (e->terms[0].type == YASM_EXPR_INT)
                yasm_intnum_calc(e->terms[0].data.intn, YASM_EXPR_NEG, NULL);
            else if (e->terms[0].type == YASM_EXPR_EXPR &&
                yasm_expr__contains(e->terms[0].data.expn, YASM_EXPR_FLOAT))
                    expr_xform_neg_helper(e->terms[0].data.expn);
            else {
                e->op = YASM_EXPR_MUL;
                e->numterms = 2;
                e->terms[1].type = YASM_EXPR_INT;
                e->terms[1].data.intn = yasm_intnum_create_int(-1);
            }
            break;
        default:
            /* Everything else.  MUL will be combined when it's leveled.
             * Make a new expr (to replace e) with -1*e.
             */
            ne = yasm_xmalloc(sizeof(yasm_expr));
            ne->op = YASM_EXPR_MUL;
            ne->line = e->line;
            ne->numterms = 2;
            ne->terms[0].type = YASM_EXPR_INT;
            ne->terms[0].data.intn = yasm_intnum_create_int(-1);
            ne->terms[1].type = YASM_EXPR_EXPR;
            ne->terms[1].data.expn = e;
            return ne;
    }
    return e;
}