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