Home | History | Annotate | Download | only in libyasm
      1 /*
      2  * Bytecode utility functions
      3  *
      4  *  Copyright (C) 2001-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-stdint.h"
     30 #include "coretype.h"
     31 
     32 #include "errwarn.h"
     33 #include "intnum.h"
     34 #include "expr.h"
     35 #include "value.h"
     36 
     37 #include "bytecode.h"
     38 
     39 
     40 typedef struct bytecode_reserve {
     41     /*@only@*/ /*@null@*/ yasm_expr *numitems; /* number of items to reserve */
     42     unsigned int itemsize;          /* size of each item (in bytes) */
     43 } bytecode_reserve;
     44 
     45 static void bc_reserve_destroy(void *contents);
     46 static void bc_reserve_print(const void *contents, FILE *f, int indent_level);
     47 static void bc_reserve_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc);
     48 static int bc_reserve_elem_size(yasm_bytecode *bc);
     49 static int bc_reserve_calc_len(yasm_bytecode *bc,
     50                                yasm_bc_add_span_func add_span,
     51                                void *add_span_data);
     52 static int bc_reserve_tobytes(yasm_bytecode *bc, unsigned char **bufp,
     53                               unsigned char *bufstart, void *d,
     54                               yasm_output_value_func output_value,
     55                               /*@null@*/ yasm_output_reloc_func output_reloc);
     56 
     57 static const yasm_bytecode_callback bc_reserve_callback = {
     58     bc_reserve_destroy,
     59     bc_reserve_print,
     60     bc_reserve_finalize,
     61     bc_reserve_elem_size,
     62     bc_reserve_calc_len,
     63     yasm_bc_expand_common,
     64     bc_reserve_tobytes,
     65     YASM_BC_SPECIAL_RESERVE
     66 };
     67 
     68 
     69 static void
     70 bc_reserve_destroy(void *contents)
     71 {
     72     bytecode_reserve *reserve = (bytecode_reserve *)contents;
     73     yasm_expr_destroy(reserve->numitems);
     74     yasm_xfree(contents);
     75 }
     76 
     77 static void
     78 bc_reserve_print(const void *contents, FILE *f, int indent_level)
     79 {
     80     const bytecode_reserve *reserve = (const bytecode_reserve *)contents;
     81     fprintf(f, "%*s_Reserve_\n", indent_level, "");
     82     fprintf(f, "%*sNum Items=", indent_level, "");
     83     yasm_expr_print(reserve->numitems, f);
     84     fprintf(f, "\n%*sItem Size=%u\n", indent_level, "", reserve->itemsize);
     85 }
     86 
     87 static void
     88 bc_reserve_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc)
     89 {
     90     bytecode_reserve *reserve = (bytecode_reserve *)bc->contents;
     91     /* multiply reserve expression into multiple */
     92     if (!bc->multiple)
     93         bc->multiple = reserve->numitems;
     94     else
     95         bc->multiple = yasm_expr_create_tree(bc->multiple, YASM_EXPR_MUL,
     96                                              reserve->numitems, bc->line);
     97     reserve->numitems = NULL;
     98 }
     99 
    100 static int
    101 bc_reserve_elem_size(yasm_bytecode *bc)
    102 {
    103     bytecode_reserve *reserve = (bytecode_reserve *)bc->contents;
    104     return reserve->itemsize;
    105 }
    106 
    107 static int
    108 bc_reserve_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span,
    109                     void *add_span_data)
    110 {
    111     bytecode_reserve *reserve = (bytecode_reserve *)bc->contents;
    112     bc->len += reserve->itemsize;
    113     return 0;
    114 }
    115 
    116 static int
    117 bc_reserve_tobytes(yasm_bytecode *bc, unsigned char **bufp,
    118                    unsigned char *bufstart, void *d,
    119                    yasm_output_value_func output_value,
    120                    /*@unused@*/ yasm_output_reloc_func output_reloc)
    121 {
    122     yasm_internal_error(N_("bc_reserve_tobytes called"));
    123     /*@notreached@*/
    124     return 1;
    125 }
    126 
    127 yasm_bytecode *
    128 yasm_bc_create_reserve(yasm_expr *numitems, unsigned int itemsize,
    129                        unsigned long line)
    130 {
    131     bytecode_reserve *reserve = yasm_xmalloc(sizeof(bytecode_reserve));
    132 
    133     /*@-mustfree@*/
    134     reserve->numitems = numitems;
    135     /*@=mustfree@*/
    136     reserve->itemsize = itemsize;
    137 
    138     return yasm_bc_create_common(&bc_reserve_callback, reserve, line);
    139 }
    140 
    141 const yasm_expr *
    142 yasm_bc_reserve_numitems(yasm_bytecode *bc, unsigned int *itemsize)
    143 {
    144     bytecode_reserve *reserve;
    145 
    146     if (bc->callback != &bc_reserve_callback)
    147         return NULL;
    148 
    149     reserve = (bytecode_reserve *)bc->contents;
    150     *itemsize = reserve->itemsize;
    151     return reserve->numitems;
    152 }
    153