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 40typedef 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 45static void bc_reserve_destroy(void *contents); 46static void bc_reserve_print(const void *contents, FILE *f, int indent_level); 47static void bc_reserve_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc); 48static int bc_reserve_elem_size(yasm_bytecode *bc); 49static int bc_reserve_calc_len(yasm_bytecode *bc, 50 yasm_bc_add_span_func add_span, 51 void *add_span_data); 52static 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 57static 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 69static void 70bc_reserve_destroy(void *contents) 71{ 72 bytecode_reserve *reserve = (bytecode_reserve *)contents; 73 yasm_expr_destroy(reserve->numitems); 74 yasm_xfree(contents); 75} 76 77static void 78bc_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 87static void 88bc_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 100static int 101bc_reserve_elem_size(yasm_bytecode *bc) 102{ 103 bytecode_reserve *reserve = (bytecode_reserve *)bc->contents; 104 return reserve->itemsize; 105} 106 107static int 108bc_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 116static int 117bc_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 127yasm_bytecode * 128yasm_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 141const yasm_expr * 142yasm_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