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
bc_reserve_destroy(void * contents)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
bc_reserve_print(const void * contents,FILE * f,int indent_level)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
bc_reserve_finalize(yasm_bytecode * bc,yasm_bytecode * prev_bc)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
bc_reserve_elem_size(yasm_bytecode * bc)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
bc_reserve_calc_len(yasm_bytecode * bc,yasm_bc_add_span_func add_span,void * add_span_data)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
bc_reserve_tobytes(yasm_bytecode * bc,unsigned char ** bufp,unsigned char * bufstart,void * d,yasm_output_value_func output_value,yasm_output_reloc_func output_reloc)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 *
yasm_bc_create_reserve(yasm_expr * numitems,unsigned int itemsize,unsigned long line)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 *
yasm_bc_reserve_numitems(yasm_bytecode * bc,unsigned int * itemsize)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