3 * \brief YASM architecture interface.
6 * Copyright (C) 2002-2007 Peter Johnson
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
11 * - Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * - Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in the
15 * documentation and/or other materials provided with the distribution.
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS''
18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE
21 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
33 /** Errors that may be returned by yasm_arch_module::create(). */
34 typedef enum yasm_arch_create_error {
35 YASM_ARCH_CREATE_OK = 0, /**< No error. */
36 YASM_ARCH_CREATE_BAD_MACHINE, /**< Unrecognized machine name. */
37 YASM_ARCH_CREATE_BAD_PARSER /**< Unrecognized parser name. */
38 } yasm_arch_create_error;
40 /** Return values for yasm_arch_module::parse_check_insnprefix(). */
41 typedef enum yasm_arch_insnprefix {
42 YASM_ARCH_NOTINSNPREFIX = 0, /**< Unrecognized */
43 YASM_ARCH_INSN, /**< An instruction */
44 YASM_ARCH_PREFIX /**< An instruction prefix */
45 } yasm_arch_insnprefix;
47 /** Types of registers / target modifiers that may be returned by
48 * yasm_arch_module::parse_check_regtmod().
50 typedef enum yasm_arch_regtmod {
51 YASM_ARCH_NOTREGTMOD = 0, /**< Unrecognized */
52 YASM_ARCH_REG, /**< A "normal" register */
53 YASM_ARCH_REGGROUP, /**< A group of indexable registers */
54 YASM_ARCH_SEGREG, /**< A segment register */
55 YASM_ARCH_TARGETMOD /**< A target modifier (for jumps) */
59 /** Base #yasm_arch structure. Must be present as the first element in any
60 * #yasm_arch implementation.
62 typedef struct yasm_arch_base {
63 /** #yasm_arch_module implementation for this architecture. */
64 const struct yasm_arch_module *module;
68 /** YASM machine subtype. A number of different machine types may be
69 * associated with a single architecture. These may be specific CPU's, but
70 * the ABI used to interface with the architecture should be the primary
71 * differentiator between machines. Some object formats (ELF) use the machine
72 * to determine parameters within the generated output.
74 typedef struct yasm_arch_machine {
75 /** One-line description of the machine. */
78 /** Keyword used to select machine. */
82 /** YASM architecture module interface.
83 * \note All "data" in parser-related functions (yasm_arch_parse_*) needs to
84 * start the parse initialized to 0 to make it okay for a parser-related
85 * function to use/check previously stored data to see if it's been
86 * called before on the same piece of data.
88 typedef struct yasm_arch_module {
89 /** One-line description of the architecture.
90 * Call yasm_arch_name() to get the name of a particular #yasm_arch.
94 /** Keyword used to select architecture.
95 * Call yasm_arch_keyword() to get the keyword of a particular #yasm_arch.
99 /** NULL-terminated list of directives. NULL if none. */
100 /*@null@*/ const yasm_directive *directives;
102 /** Create architecture.
103 * Module-level implementation of yasm_arch_create().
104 * Call yasm_arch_create() instead of calling this function.
106 /*@only@*/ yasm_arch * (*create) (const char *machine, const char *parser,
107 /*@out@*/ yasm_arch_create_error *error);
109 /** Module-level implementation of yasm_arch_destroy().
110 * Call yasm_arch_destroy() instead of calling this function.
112 void (*destroy) (/*@only@*/ yasm_arch *arch);
114 /** Module-level implementation of yasm_arch_get_machine().
115 * Call yasm_arch_get_machine() instead of calling this function.
117 const char * (*get_machine) (const yasm_arch *arch);
119 /** Module-level implementation of yasm_arch_get_address_size().
120 * Call yasm_arch_get_address_size() instead of calling this function.
122 unsigned int (*get_address_size) (const yasm_arch *arch);
124 /** Module-level implementation of yasm_arch_set_var().
125 * Call yasm_arch_set_var() instead of calling this function.
127 int (*set_var) (yasm_arch *arch, const char *var, unsigned long val);
129 /** Module-level implementation of yasm_arch_parse_check_insnprefix().
130 * Call yasm_arch_parse_check_insnprefix() instead of calling this function.
132 yasm_arch_insnprefix (*parse_check_insnprefix)
133 (yasm_arch *arch, const char *id, size_t id_len, unsigned long line,
134 /*@out@*/ /*@only@*/ yasm_bytecode **bc, /*@out@*/ uintptr_t *prefix);
136 /** Module-level implementation of yasm_arch_parse_check_regtmod().
137 * Call yasm_arch_parse_check_regtmod() instead of calling this function.
139 yasm_arch_regtmod (*parse_check_regtmod)
140 (yasm_arch *arch, const char *id, size_t id_len,
141 /*@out@*/ uintptr_t *data);
143 /** Module-level implementation of yasm_arch_get_fill().
144 * Call yasm_arch_get_fill() instead of calling this function.
146 const unsigned char ** (*get_fill) (const yasm_arch *arch);
148 /** Module-level implementation of yasm_arch_floatnum_tobytes().
149 * Call yasm_arch_floatnum_tobytes() instead of calling this function.
151 int (*floatnum_tobytes) (yasm_arch *arch, const yasm_floatnum *flt,
152 unsigned char *buf, size_t destsize,
153 size_t valsize, size_t shift, int warn);
155 /** Module-level implementation of yasm_arch_intnum_tobytes().
156 * Call yasm_arch_intnum_tobytes() instead of calling this function.
158 int (*intnum_tobytes) (yasm_arch *arch, const yasm_intnum *intn,
159 unsigned char *buf, size_t destsize, size_t valsize,
160 int shift, const yasm_bytecode *bc,
163 /** Module-level implementation of yasm_arch_get_reg_size().
164 * Call yasm_arch_get_reg_size() instead of calling this function.
166 unsigned int (*get_reg_size) (yasm_arch *arch, uintptr_t reg);
168 /** Module-level implementation of yasm_arch_reggroup_get_reg().
169 * Call yasm_arch_reggroup_get_reg() instead of calling this function.
171 uintptr_t (*reggroup_get_reg) (yasm_arch *arch, uintptr_t reggroup,
172 unsigned long regindex);
174 /** Module-level implementation of yasm_arch_reg_print().
175 * Call yasm_arch_reg_print() instead of calling this function.
177 void (*reg_print) (yasm_arch *arch, uintptr_t reg, FILE *f);
179 /** Module-level implementation of yasm_arch_segreg_print().
180 * Call yasm_arch_segreg_print() instead of calling this function.
182 void (*segreg_print) (yasm_arch *arch, uintptr_t segreg, FILE *f);
184 /** Module-level implementation of yasm_arch_ea_create().
185 * Call yasm_arch_ea_create() instead of calling this function.
187 yasm_effaddr * (*ea_create) (yasm_arch *arch, /*@keep@*/ yasm_expr *e);
189 /** Module-level implementation of yasm_arch_ea_destroy().
190 * Call yasm_arch_ea_destroy() instead of calling this function.
192 void (*ea_destroy) (/*@only@*/ yasm_effaddr *ea);
194 /** Module-level implementation of yasm_arch_ea_print().
195 * Call yasm_arch_ea_print() instead of calling this function.
197 void (*ea_print) (const yasm_effaddr *ea, FILE *f, int indent_level);
199 /** Module-level implementation of yasm_arch_create_empty_insn().
200 * Call yasm_arch_create_empty_insn() instead of calling this function.
202 /*@only@*/ yasm_bytecode * (*create_empty_insn) (yasm_arch *arch,
205 /** NULL-terminated list of machines for this architecture.
206 * Call yasm_arch_get_machine() to get the active machine of a particular
209 const yasm_arch_machine *machines;
211 /** Default machine keyword.
212 * Call yasm_arch_get_machine() to get the active machine of a particular
215 const char *default_machine_keyword;
217 /** Canonical "word" size in bits.
218 * Call yasm_arch_wordsize() to get the word size of a particular
221 unsigned int wordsize;
223 /** Worst case minimum instruction length in bytes.
224 * Call yasm_arch_min_insn_len() to get the minimum instruction length of
225 * a particular #yasm_arch.
227 unsigned int min_insn_len;
230 /** Get the one-line description of an architecture.
231 * \param arch architecture
232 * \return One-line description of architecture.
234 const char *yasm_arch_name(const yasm_arch *arch);
236 /** Get the keyword used to select an architecture.
237 * \param arch architecture
238 * \return Architecture keyword.
240 const char *yasm_arch_keyword(const yasm_arch *arch);
242 /** Get the word size of an architecture.
243 * \param arch architecture
244 * \return Word size (in bits).
246 unsigned int yasm_arch_wordsize(const yasm_arch *arch);
248 /** Get the minimum instruction length of an architecture.
249 * \param arch architecture
250 * \return Minimum instruction length (in bytes).
252 unsigned int yasm_arch_min_insn_len(const yasm_arch *arch);
254 /** Create architecture.
255 * \param module architecture module
256 * \param machine keyword of machine in use (must be one listed in
257 * #yasm_arch_module.machines)
258 * \param parser keyword of parser in use
259 * \param error error return value
260 * \return NULL on error (error returned in error parameter), otherwise new
263 /*@only@*/ yasm_arch *yasm_arch_create(const yasm_arch_module *module,
264 const char *machine, const char *parser,
265 /*@out@*/ yasm_arch_create_error *error);
267 /** Clean up, free any architecture-allocated memory.
268 * \param arch architecture
270 void yasm_arch_destroy(/*@only@*/ yasm_arch *arch);
272 /** Get architecture's active machine name.
273 * \param arch architecture
274 * \return Active machine name.
276 const char *yasm_arch_get_machine(const yasm_arch *arch);
278 /** Get architecture's active address size, in bits.
279 * \param arch architecture
280 * \return Active address size (in bits).
282 unsigned int yasm_arch_get_address_size(const yasm_arch *arch);
284 /** Set any arch-specific variables. For example, "mode_bits" in x86.
285 * \param arch architecture
286 * \param var variable name
287 * \param val value to set
288 * \return Zero on success, non-zero on failure (variable does not exist).
290 int yasm_arch_set_var(yasm_arch *arch, const char *var, unsigned long val);
292 /** Check an generic identifier to see if it matches architecture specific
293 * names for instructions or instruction prefixes. Unrecognized identifiers
294 * should return #YASM_ARCH_NOTINSNPREFIX so they can be treated as normal
295 * symbols. Any additional data beyond just the type (almost always necessary)
296 * should be returned into the space provided by the data parameter.
297 * \param arch architecture
298 * \param id identifier as in the input file
299 * \param id_len length of id string
300 * \param line virtual line
301 * \param bc for instructions, yasm_insn-based bytecode is returned
302 * (and NULL otherwise)
303 * \param prefix for prefixes, yasm_arch-specific value is returned
305 * \return Identifier type (#YASM_ARCH_NOTINSNPREFIX if unrecognized)
307 yasm_arch_insnprefix yasm_arch_parse_check_insnprefix
308 (yasm_arch *arch, const char *id, size_t id_len, unsigned long line,
309 /*@out@*/ /*@only@*/ yasm_bytecode **bc, /*@out@*/ uintptr_t *prefix);
311 /** Check an generic identifier to see if it matches architecture specific
312 * names for registers or target modifiers. Unrecognized identifiers should
313 * return #YASM_ARCH_NOTREGTMOD. Any additional data beyond just the type
314 * (almost always necessary) should be returned into the space provided by the
316 * \param arch architecture
317 * \param id identifier as in the input file
318 * \param id_len length of id string
319 * \param data extra identification information (yasm_arch-specific)
321 * \return Identifier type (#YASM_ARCH_NOTREGTMOD if unrecognized)
323 yasm_arch_regtmod yasm_arch_parse_check_regtmod
324 (yasm_arch *arch, const char *id, size_t id_len,
325 /*@out@*/ uintptr_t *data);
327 /** Get NOP fill patterns for 1-15 bytes of fill.
328 * \param arch architecture
329 * \return 16-entry array of arrays; [0] is unused, [1] - [15] point to arrays
330 * of 1-15 bytes (respectively) in length.
332 const unsigned char **yasm_arch_get_fill(const yasm_arch *arch);
334 /** Output #yasm_floatnum to buffer. Puts the value into the least
335 * significant bits of the destination, or may be shifted into more
336 * significant bits by the shift parameter. The destination bits are
337 * cleared before being set.
338 * Architecture-specific because of endianness.
339 * \param arch architecture
340 * \param flt floating point value
341 * \param buf buffer to write into
342 * \param destsize destination size (in bytes)
343 * \param valsize size (in bits)
344 * \param shift left shift (in bits)
345 * \param warn enables standard overflow/underflow warnings
346 * \return Nonzero on error.
348 int yasm_arch_floatnum_tobytes(yasm_arch *arch, const yasm_floatnum *flt,
349 unsigned char *buf, size_t destsize,
350 size_t valsize, size_t shift, int warn);
352 /** Output #yasm_intnum to buffer. Puts the value into the least
353 * significant bits of the destination, or may be shifted into more
354 * significant bits by the shift parameter. The destination bits are
355 * cleared before being set.
356 * \param arch architecture
357 * \param intn integer value
358 * \param buf buffer to write into
359 * \param destsize destination size (in bytes)
360 * \param valsize size (in bits)
361 * \param shift left shift (in bits); may be negative to specify right
362 * shift (standard warnings include truncation to boundary)
363 * \param bc bytecode being output ("parent" of value)
364 * \param warn enables standard warnings (value doesn't fit into
366 * \return Nonzero on error.
368 int yasm_arch_intnum_tobytes(yasm_arch *arch, const yasm_intnum *intn,
369 unsigned char *buf, size_t destsize,
370 size_t valsize, int shift,
371 const yasm_bytecode *bc, int warn);
373 /** Get the equivalent size of a register in bits.
374 * \param arch architecture
375 * \param reg register
376 * \return 0 if there is no suitable equivalent size, otherwise the size.
378 unsigned int yasm_arch_get_reg_size(yasm_arch *arch, uintptr_t reg);
380 /** Get a specific register of a register group, based on the register
381 * group and the index within the group.
382 * \param arch architecture
383 * \param reggroup register group
384 * \param regindex register index
385 * \return 0 if regindex is not valid for that register group, otherwise the
386 * specific register value.
388 uintptr_t yasm_arch_reggroup_get_reg(yasm_arch *arch, uintptr_t reggroup,
389 unsigned long regindex);
391 /** Print a register. For debugging purposes.
392 * \param arch architecture
393 * \param reg register
396 void yasm_arch_reg_print(yasm_arch *arch, uintptr_t reg, FILE *f);
398 /** Print a segment register. For debugging purposes.
399 * \param arch architecture
400 * \param segreg segment register
403 void yasm_arch_segreg_print(yasm_arch *arch, uintptr_t segreg, FILE *f);
405 /** Create an effective address from an expression.
406 * \param arch architecture
407 * \param e expression (kept, do not delete)
408 * \return Newly allocated effective address.
410 yasm_effaddr *yasm_arch_ea_create(yasm_arch *arch, /*@keep@*/ yasm_expr *e);
412 /** Delete (free allocated memory for) an effective address.
413 * \param arch architecture
414 * \param ea effective address (only pointer to it).
416 void yasm_arch_ea_destroy(yasm_arch *arch, /*@only@*/ yasm_effaddr *ea);
418 /** Print an effective address. For debugging purposes.
419 * \param arch architecture
420 * \param ea effective address
422 * \param indent_level indentation level
424 void yasm_arch_ea_print(const yasm_arch *arch, const yasm_effaddr *ea,
425 FILE *f, int indent_level);
427 /** Create a bytecode that represents a single empty (0 length) instruction.
428 * This is used for handling solitary prefixes.
429 * \param arch architecture
430 * \param line virtual line (from yasm_linemap)
431 * \return Newly allocated bytecode.
433 /*@only@*/ yasm_bytecode *yasm_arch_create_empty_insn(yasm_arch *arch,
438 /* Inline macro implementations for arch functions */
440 #define yasm_arch_name(arch) \
441 (((yasm_arch_base *)arch)->module->name)
442 #define yasm_arch_keyword(arch) \
443 (((yasm_arch_base *)arch)->module->keyword)
444 #define yasm_arch_wordsize(arch) \
445 (((yasm_arch_base *)arch)->module->wordsize)
446 #define yasm_arch_min_insn_len(arch) \
447 (((yasm_arch_base *)arch)->module->min_insn_len)
449 #define yasm_arch_create(module, machine, parser, error) \
450 module->create(machine, parser, error)
452 #define yasm_arch_destroy(arch) \
453 ((yasm_arch_base *)arch)->module->destroy(arch)
454 #define yasm_arch_get_machine(arch) \
455 ((yasm_arch_base *)arch)->module->get_machine(arch)
456 #define yasm_arch_get_address_size(arch) \
457 ((yasm_arch_base *)arch)->module->get_address_size(arch)
458 #define yasm_arch_set_var(arch, var, val) \
459 ((yasm_arch_base *)arch)->module->set_var(arch, var, val)
460 #define yasm_arch_parse_check_insnprefix(arch, id, id_len, line, bc, prefix) \
461 ((yasm_arch_base *)arch)->module->parse_check_insnprefix \
462 (arch, id, id_len, line, bc, prefix)
463 #define yasm_arch_parse_check_regtmod(arch, id, id_len, data) \
464 ((yasm_arch_base *)arch)->module->parse_check_regtmod \
465 (arch, id, id_len, data)
466 #define yasm_arch_get_fill(arch) \
467 ((yasm_arch_base *)arch)->module->get_fill(arch)
468 #define yasm_arch_floatnum_tobytes(arch, flt, buf, destsize, valsize, shift, \
470 ((yasm_arch_base *)arch)->module->floatnum_tobytes \
471 (arch, flt, buf, destsize, valsize, shift, warn)
472 #define yasm_arch_intnum_tobytes(arch, intn, buf, destsize, valsize, shift, \
474 ((yasm_arch_base *)arch)->module->intnum_tobytes \
475 (arch, intn, buf, destsize, valsize, shift, bc, warn)
476 #define yasm_arch_get_reg_size(arch, reg) \
477 ((yasm_arch_base *)arch)->module->get_reg_size(arch, reg)
478 #define yasm_arch_reggroup_get_reg(arch, regg, regi) \
479 ((yasm_arch_base *)arch)->module->reggroup_get_reg(arch, regg, regi)
480 #define yasm_arch_reg_print(arch, reg, f) \
481 ((yasm_arch_base *)arch)->module->reg_print(arch, reg, f)
482 #define yasm_arch_segreg_print(arch, segreg, f) \
483 ((yasm_arch_base *)arch)->module->segreg_print(arch, segreg, f)
484 #define yasm_arch_ea_create(arch, e) \
485 ((yasm_arch_base *)arch)->module->ea_create(arch, e)
486 #define yasm_arch_ea_destroy(arch, ea) \
487 ((yasm_arch_base *)arch)->module->ea_destroy(ea)
488 #define yasm_arch_ea_print(arch, ea, f, i) \
489 ((yasm_arch_base *)arch)->module->ea_print(ea, f, i)
490 #define yasm_arch_create_empty_insn(arch, line) \
491 ((yasm_arch_base *)arch)->module->create_empty_insn(arch, line)