OLD | NEW |
1 /* | 1 /* |
2 * LC-3b bytecode utility functions | 2 * LC-3b bytecode utility functions |
3 * | 3 * |
4 * Copyright (C) 2003-2007 Peter Johnson | 4 * Copyright (C) 2003-2007 Peter Johnson |
5 * | 5 * |
6 * Redistribution and use in source and binary forms, with or without | 6 * Redistribution and use in source and binary forms, with or without |
7 * modification, are permitted provided that the following conditions | 7 * modification, are permitted provided that the following conditions |
8 * are met: | 8 * are met: |
9 * 1. Redistributions of source code must retain the above copyright | 9 * 1. Redistributions of source code must retain the above copyright |
10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
11 * 2. Redistributions in binary form must reproduce the above copyright | 11 * 2. Redistributions in binary form must reproduce the above copyright |
12 * notice, this list of conditions and the following disclaimer in the | 12 * notice, this list of conditions and the following disclaimer in the |
13 * documentation and/or other materials provided with the distribution. | 13 * documentation and/or other materials provided with the distribution. |
14 * | 14 * |
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS'' | 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 | 16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE | 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE | 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE |
19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | 19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR |
20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF | 20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF |
21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS | 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 | 22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN |
23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) | 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 | 24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
25 * POSSIBILITY OF SUCH DAMAGE. | 25 * POSSIBILITY OF SUCH DAMAGE. |
26 */ | 26 */ |
27 #include <util.h> | 27 #include <util.h> |
28 /*@unused@*/ RCSID("$Id: lc3bbc.c 2130 2008-10-07 05:38:11Z peter $"); | |
29 | 28 |
30 #include <libyasm.h> | 29 #include <libyasm.h> |
31 | 30 |
32 #include "lc3barch.h" | 31 #include "lc3barch.h" |
33 | 32 |
34 | 33 |
35 /* Bytecode callback function prototypes */ | 34 /* Bytecode callback function prototypes */ |
36 | 35 |
37 static void lc3b_bc_insn_destroy(void *contents); | 36 static void lc3b_bc_insn_destroy(void *contents); |
38 static void lc3b_bc_insn_print(const void *contents, FILE *f, | 37 static void lc3b_bc_insn_print(const void *contents, FILE *f, |
39 int indent_level); | 38 int indent_level); |
40 static int lc3b_bc_insn_calc_len(yasm_bytecode *bc, | 39 static int lc3b_bc_insn_calc_len(yasm_bytecode *bc, |
41 yasm_bc_add_span_func add_span, | 40 yasm_bc_add_span_func add_span, |
42 void *add_span_data); | 41 void *add_span_data); |
43 static int lc3b_bc_insn_expand(yasm_bytecode *bc, int span, long old_val, | 42 static int lc3b_bc_insn_expand(yasm_bytecode *bc, int span, long old_val, |
44 long new_val, /*@out@*/ long *neg_thres, | 43 long new_val, /*@out@*/ long *neg_thres, |
45 /*@out@*/ long *pos_thres); | 44 /*@out@*/ long *pos_thres); |
46 static int lc3b_bc_insn_tobytes(yasm_bytecode *bc, unsigned char **bufp, | 45 static int lc3b_bc_insn_tobytes(yasm_bytecode *bc, unsigned char **bufp, |
| 46 unsigned char *bufstart, |
47 void *d, yasm_output_value_func output_value, | 47 void *d, yasm_output_value_func output_value, |
48 /*@null@*/ yasm_output_reloc_func output_reloc); | 48 /*@null@*/ yasm_output_reloc_func output_reloc); |
49 | 49 |
50 /* Bytecode callback structures */ | 50 /* Bytecode callback structures */ |
51 | 51 |
52 static const yasm_bytecode_callback lc3b_bc_callback_insn = { | 52 static const yasm_bytecode_callback lc3b_bc_callback_insn = { |
53 lc3b_bc_insn_destroy, | 53 lc3b_bc_insn_destroy, |
54 lc3b_bc_insn_print, | 54 lc3b_bc_insn_print, |
55 yasm_bc_finalize_common, | 55 yasm_bc_finalize_common, |
56 NULL, | 56 NULL, |
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
158 | 158 |
159 static int | 159 static int |
160 lc3b_bc_insn_expand(yasm_bytecode *bc, int span, long old_val, long new_val, | 160 lc3b_bc_insn_expand(yasm_bytecode *bc, int span, long old_val, long new_val, |
161 /*@out@*/ long *neg_thres, /*@out@*/ long *pos_thres) | 161 /*@out@*/ long *neg_thres, /*@out@*/ long *pos_thres) |
162 { | 162 { |
163 yasm_error_set(YASM_ERROR_VALUE, N_("jump target out of range")); | 163 yasm_error_set(YASM_ERROR_VALUE, N_("jump target out of range")); |
164 return -1; | 164 return -1; |
165 } | 165 } |
166 | 166 |
167 static int | 167 static int |
168 lc3b_bc_insn_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d, | 168 lc3b_bc_insn_tobytes(yasm_bytecode *bc, unsigned char **bufp, |
| 169 unsigned char *bufstart, void *d, |
169 yasm_output_value_func output_value, | 170 yasm_output_value_func output_value, |
170 /*@unused@*/ yasm_output_reloc_func output_reloc) | 171 /*@unused@*/ yasm_output_reloc_func output_reloc) |
171 { | 172 { |
172 lc3b_insn *insn = (lc3b_insn *)bc->contents; | 173 lc3b_insn *insn = (lc3b_insn *)bc->contents; |
173 /*@only@*/ yasm_intnum *delta; | 174 /*@only@*/ yasm_intnum *delta; |
| 175 unsigned long buf_off = (unsigned long)(*bufp - bufstart); |
174 | 176 |
175 /* Output opcode */ | 177 /* Output opcode */ |
176 YASM_SAVE_16_L(*bufp, insn->opcode); | 178 YASM_SAVE_16_L(*bufp, insn->opcode); |
177 | 179 |
178 /* Insert immediate into opcode. */ | 180 /* Insert immediate into opcode. */ |
179 switch (insn->imm_type) { | 181 switch (insn->imm_type) { |
180 case LC3B_IMM_NONE: | 182 case LC3B_IMM_NONE: |
181 break; | 183 break; |
182 case LC3B_IMM_4: | 184 case LC3B_IMM_4: |
183 insn->imm.size = 4; | 185 insn->imm.size = 4; |
184 if (output_value(&insn->imm, *bufp, 2, 0, bc, 1, d)) | 186 if (output_value(&insn->imm, *bufp, 2, buf_off, bc, 1, d)) |
185 return 1; | 187 return 1; |
186 break; | 188 break; |
187 case LC3B_IMM_5: | 189 case LC3B_IMM_5: |
188 insn->imm.size = 5; | 190 insn->imm.size = 5; |
189 insn->imm.sign = 1; | 191 insn->imm.sign = 1; |
190 if (output_value(&insn->imm, *bufp, 2, 0, bc, 1, d)) | 192 if (output_value(&insn->imm, *bufp, 2, buf_off, bc, 1, d)) |
191 return 1; | 193 return 1; |
192 break; | 194 break; |
193 case LC3B_IMM_6_WORD: | 195 case LC3B_IMM_6_WORD: |
194 insn->imm.size = 6; | 196 insn->imm.size = 6; |
195 if (output_value(&insn->imm, *bufp, 2, 0, bc, 1, d)) | 197 if (output_value(&insn->imm, *bufp, 2, buf_off, bc, 1, d)) |
196 return 1; | 198 return 1; |
197 break; | 199 break; |
198 case LC3B_IMM_6_BYTE: | 200 case LC3B_IMM_6_BYTE: |
199 insn->imm.size = 6; | 201 insn->imm.size = 6; |
200 insn->imm.sign = 1; | 202 insn->imm.sign = 1; |
201 if (output_value(&insn->imm, *bufp, 2, 0, bc, 1, d)) | 203 if (output_value(&insn->imm, *bufp, 2, buf_off, bc, 1, d)) |
202 return 1; | 204 return 1; |
203 break; | 205 break; |
204 case LC3B_IMM_8: | 206 case LC3B_IMM_8: |
205 insn->imm.size = 8; | 207 insn->imm.size = 8; |
206 if (output_value(&insn->imm, *bufp, 2, 0, bc, 1, d)) | 208 if (output_value(&insn->imm, *bufp, 2, buf_off, bc, 1, d)) |
207 return 1; | 209 return 1; |
208 break; | 210 break; |
209 case LC3B_IMM_9_PC: | 211 case LC3B_IMM_9_PC: |
210 /* Adjust relative displacement to end of bytecode */ | 212 /* Adjust relative displacement to end of bytecode */ |
211 delta = yasm_intnum_create_int(-1); | 213 delta = yasm_intnum_create_int(-1); |
212 if (!insn->imm.abs) | 214 if (!insn->imm.abs) |
213 insn->imm.abs = yasm_expr_create_ident(yasm_expr_int(delta), | 215 insn->imm.abs = yasm_expr_create_ident(yasm_expr_int(delta), |
214 bc->line); | 216 bc->line); |
215 else | 217 else |
216 insn->imm.abs = | 218 insn->imm.abs = |
217 yasm_expr_create(YASM_EXPR_ADD, | 219 yasm_expr_create(YASM_EXPR_ADD, |
218 yasm_expr_expr(insn->imm.abs), | 220 yasm_expr_expr(insn->imm.abs), |
219 yasm_expr_int(delta), bc->line); | 221 yasm_expr_int(delta), bc->line); |
220 | 222 |
221 insn->imm.size = 9; | 223 insn->imm.size = 9; |
222 insn->imm.sign = 1; | 224 insn->imm.sign = 1; |
223 if (output_value(&insn->imm, *bufp, 2, 0, bc, 1, d)) | 225 if (output_value(&insn->imm, *bufp, 2, buf_off, bc, 1, d)) |
224 return 1; | 226 return 1; |
225 break; | 227 break; |
226 case LC3B_IMM_9: | 228 case LC3B_IMM_9: |
227 insn->imm.size = 9; | 229 insn->imm.size = 9; |
228 if (output_value(&insn->imm, *bufp, 2, 0, bc, 1, d)) | 230 if (output_value(&insn->imm, *bufp, 2, buf_off, bc, 1, d)) |
229 return 1; | 231 return 1; |
230 break; | 232 break; |
231 default: | 233 default: |
232 yasm_internal_error(N_("Unrecognized immediate type")); | 234 yasm_internal_error(N_("Unrecognized immediate type")); |
233 } | 235 } |
234 | 236 |
235 *bufp += 2; /* all instructions are 2 bytes in size */ | 237 *bufp += 2; /* all instructions are 2 bytes in size */ |
236 return 0; | 238 return 0; |
237 } | 239 } |
238 | 240 |
239 int | 241 int |
240 yasm_lc3b__intnum_tobytes(yasm_arch *arch, const yasm_intnum *intn, | 242 yasm_lc3b__intnum_tobytes(yasm_arch *arch, const yasm_intnum *intn, |
241 unsigned char *buf, size_t destsize, size_t valsize, | 243 unsigned char *buf, size_t destsize, size_t valsize, |
242 int shift, const yasm_bytecode *bc, int warn) | 244 int shift, const yasm_bytecode *bc, int warn) |
243 { | 245 { |
244 /* Write value out. */ | 246 /* Write value out. */ |
245 yasm_intnum_get_sized(intn, buf, destsize, valsize, shift, 0, warn); | 247 yasm_intnum_get_sized(intn, buf, destsize, valsize, shift, 0, warn); |
246 return 0; | 248 return 0; |
247 } | 249 } |
OLD | NEW |