arch.h 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495
  1. /**
  2. * \file libyasm/arch.h
  3. * \brief YASM architecture interface.
  4. *
  5. * \license
  6. * Copyright (C) 2002-2007 Peter Johnson
  7. *
  8. * Redistribution and use in source and binary forms, with or without
  9. * modification, are permitted provided that the following conditions
  10. * are met:
  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.
  16. *
  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.
  28. * \endlicense
  29. */
  30. #ifndef YASM_ARCH_H
  31. #define YASM_ARCH_H
  32. /** Errors that may be returned by yasm_arch_module::create(). */
  33. typedef enum yasm_arch_create_error {
  34. YASM_ARCH_CREATE_OK = 0, /**< No error. */
  35. YASM_ARCH_CREATE_BAD_MACHINE, /**< Unrecognized machine name. */
  36. YASM_ARCH_CREATE_BAD_PARSER /**< Unrecognized parser name. */
  37. } yasm_arch_create_error;
  38. /** Return values for yasm_arch_module::parse_check_insnprefix(). */
  39. typedef enum yasm_arch_insnprefix {
  40. YASM_ARCH_NOTINSNPREFIX = 0, /**< Unrecognized */
  41. YASM_ARCH_INSN, /**< An instruction */
  42. YASM_ARCH_PREFIX /**< An instruction prefix */
  43. } yasm_arch_insnprefix;
  44. /** Types of registers / target modifiers that may be returned by
  45. * yasm_arch_module::parse_check_regtmod().
  46. */
  47. typedef enum yasm_arch_regtmod {
  48. YASM_ARCH_NOTREGTMOD = 0, /**< Unrecognized */
  49. YASM_ARCH_REG, /**< A "normal" register */
  50. YASM_ARCH_REGGROUP, /**< A group of indexable registers */
  51. YASM_ARCH_SEGREG, /**< A segment register */
  52. YASM_ARCH_TARGETMOD /**< A target modifier (for jumps) */
  53. } yasm_arch_regtmod;
  54. #ifndef YASM_DOXYGEN
  55. /** Base #yasm_arch structure. Must be present as the first element in any
  56. * #yasm_arch implementation.
  57. */
  58. typedef struct yasm_arch_base {
  59. /** #yasm_arch_module implementation for this architecture. */
  60. const struct yasm_arch_module *module;
  61. } yasm_arch_base;
  62. #endif
  63. /** YASM machine subtype. A number of different machine types may be
  64. * associated with a single architecture. These may be specific CPU's, but
  65. * the ABI used to interface with the architecture should be the primary
  66. * differentiator between machines. Some object formats (ELF) use the machine
  67. * to determine parameters within the generated output.
  68. */
  69. typedef struct yasm_arch_machine {
  70. /** One-line description of the machine. */
  71. const char *name;
  72. /** Keyword used to select machine. */
  73. const char *keyword;
  74. } yasm_arch_machine;
  75. /** YASM architecture module interface.
  76. * \note All "data" in parser-related functions (yasm_arch_parse_*) needs to
  77. * start the parse initialized to 0 to make it okay for a parser-related
  78. * function to use/check previously stored data to see if it's been
  79. * called before on the same piece of data.
  80. */
  81. typedef struct yasm_arch_module {
  82. /** One-line description of the architecture.
  83. * Call yasm_arch_name() to get the name of a particular #yasm_arch.
  84. */
  85. const char *name;
  86. /** Keyword used to select architecture.
  87. * Call yasm_arch_keyword() to get the keyword of a particular #yasm_arch.
  88. */
  89. const char *keyword;
  90. /** NULL-terminated list of directives. NULL if none. */
  91. /*@null@*/ const yasm_directive *directives;
  92. /** Create architecture.
  93. * Module-level implementation of yasm_arch_create().
  94. * Call yasm_arch_create() instead of calling this function.
  95. */
  96. /*@only@*/ yasm_arch * (*create) (const char *machine, const char *parser,
  97. /*@out@*/ yasm_arch_create_error *error);
  98. /** Module-level implementation of yasm_arch_destroy().
  99. * Call yasm_arch_destroy() instead of calling this function.
  100. */
  101. void (*destroy) (/*@only@*/ yasm_arch *arch);
  102. /** Module-level implementation of yasm_arch_get_machine().
  103. * Call yasm_arch_get_machine() instead of calling this function.
  104. */
  105. const char * (*get_machine) (const yasm_arch *arch);
  106. /** Module-level implementation of yasm_arch_get_address_size().
  107. * Call yasm_arch_get_address_size() instead of calling this function.
  108. */
  109. unsigned int (*get_address_size) (const yasm_arch *arch);
  110. /** Module-level implementation of yasm_arch_set_var().
  111. * Call yasm_arch_set_var() instead of calling this function.
  112. */
  113. int (*set_var) (yasm_arch *arch, const char *var, unsigned long val);
  114. /** Module-level implementation of yasm_arch_parse_check_insnprefix().
  115. * Call yasm_arch_parse_check_insnprefix() instead of calling this function.
  116. */
  117. yasm_arch_insnprefix (*parse_check_insnprefix)
  118. (yasm_arch *arch, const char *id, size_t id_len, unsigned long line,
  119. /*@out@*/ /*@only@*/ yasm_bytecode **bc, /*@out@*/ uintptr_t *prefix);
  120. /** Module-level implementation of yasm_arch_parse_check_regtmod().
  121. * Call yasm_arch_parse_check_regtmod() instead of calling this function.
  122. */
  123. yasm_arch_regtmod (*parse_check_regtmod)
  124. (yasm_arch *arch, const char *id, size_t id_len,
  125. /*@out@*/ uintptr_t *data);
  126. /** Module-level implementation of yasm_arch_get_fill().
  127. * Call yasm_arch_get_fill() instead of calling this function.
  128. */
  129. const unsigned char ** (*get_fill) (const yasm_arch *arch);
  130. /** Module-level implementation of yasm_arch_floatnum_tobytes().
  131. * Call yasm_arch_floatnum_tobytes() instead of calling this function.
  132. */
  133. int (*floatnum_tobytes) (yasm_arch *arch, const yasm_floatnum *flt,
  134. unsigned char *buf, size_t destsize,
  135. size_t valsize, size_t shift, int warn);
  136. /** Module-level implementation of yasm_arch_intnum_tobytes().
  137. * Call yasm_arch_intnum_tobytes() instead of calling this function.
  138. */
  139. int (*intnum_tobytes) (yasm_arch *arch, const yasm_intnum *intn,
  140. unsigned char *buf, size_t destsize, size_t valsize,
  141. int shift, const yasm_bytecode *bc,
  142. int warn);
  143. /** Module-level implementation of yasm_arch_get_reg_size().
  144. * Call yasm_arch_get_reg_size() instead of calling this function.
  145. */
  146. unsigned int (*get_reg_size) (yasm_arch *arch, uintptr_t reg);
  147. /** Module-level implementation of yasm_arch_reggroup_get_reg().
  148. * Call yasm_arch_reggroup_get_reg() instead of calling this function.
  149. */
  150. uintptr_t (*reggroup_get_reg) (yasm_arch *arch, uintptr_t reggroup,
  151. unsigned long regindex);
  152. /** Module-level implementation of yasm_arch_reg_print().
  153. * Call yasm_arch_reg_print() instead of calling this function.
  154. */
  155. void (*reg_print) (yasm_arch *arch, uintptr_t reg, FILE *f);
  156. /** Module-level implementation of yasm_arch_segreg_print().
  157. * Call yasm_arch_segreg_print() instead of calling this function.
  158. */
  159. void (*segreg_print) (yasm_arch *arch, uintptr_t segreg, FILE *f);
  160. /** Module-level implementation of yasm_arch_ea_create().
  161. * Call yasm_arch_ea_create() instead of calling this function.
  162. */
  163. yasm_effaddr * (*ea_create) (yasm_arch *arch, /*@keep@*/ yasm_expr *e);
  164. /** Module-level implementation of yasm_arch_ea_destroy().
  165. * Call yasm_arch_ea_destroy() instead of calling this function.
  166. */
  167. void (*ea_destroy) (/*@only@*/ yasm_effaddr *ea);
  168. /** Module-level implementation of yasm_arch_ea_print().
  169. * Call yasm_arch_ea_print() instead of calling this function.
  170. */
  171. void (*ea_print) (const yasm_effaddr *ea, FILE *f, int indent_level);
  172. /** Module-level implementation of yasm_arch_create_empty_insn().
  173. * Call yasm_arch_create_empty_insn() instead of calling this function.
  174. */
  175. /*@only@*/ yasm_bytecode * (*create_empty_insn) (yasm_arch *arch,
  176. unsigned long line);
  177. /** NULL-terminated list of machines for this architecture.
  178. * Call yasm_arch_get_machine() to get the active machine of a particular
  179. * #yasm_arch.
  180. */
  181. const yasm_arch_machine *machines;
  182. /** Default machine keyword.
  183. * Call yasm_arch_get_machine() to get the active machine of a particular
  184. * #yasm_arch.
  185. */
  186. const char *default_machine_keyword;
  187. /** Canonical "word" size in bits.
  188. * Call yasm_arch_wordsize() to get the word size of a particular
  189. * #yasm_arch.
  190. */
  191. unsigned int wordsize;
  192. /** Worst case minimum instruction length in bytes.
  193. * Call yasm_arch_min_insn_len() to get the minimum instruction length of
  194. * a particular #yasm_arch.
  195. */
  196. unsigned int min_insn_len;
  197. } yasm_arch_module;
  198. /** Get the one-line description of an architecture.
  199. * \param arch architecture
  200. * \return One-line description of architecture.
  201. */
  202. const char *yasm_arch_name(const yasm_arch *arch);
  203. /** Get the keyword used to select an architecture.
  204. * \param arch architecture
  205. * \return Architecture keyword.
  206. */
  207. const char *yasm_arch_keyword(const yasm_arch *arch);
  208. /** Get the word size of an architecture.
  209. * \param arch architecture
  210. * \return Word size (in bits).
  211. */
  212. unsigned int yasm_arch_wordsize(const yasm_arch *arch);
  213. /** Get the minimum instruction length of an architecture.
  214. * \param arch architecture
  215. * \return Minimum instruction length (in bytes).
  216. */
  217. unsigned int yasm_arch_min_insn_len(const yasm_arch *arch);
  218. /** Create architecture.
  219. * \param module architecture module
  220. * \param machine keyword of machine in use (must be one listed in
  221. * #yasm_arch_module.machines)
  222. * \param parser keyword of parser in use
  223. * \param error error return value
  224. * \return NULL on error (error returned in error parameter), otherwise new
  225. * architecture.
  226. */
  227. /*@only@*/ yasm_arch *yasm_arch_create(const yasm_arch_module *module,
  228. const char *machine, const char *parser,
  229. /*@out@*/ yasm_arch_create_error *error);
  230. /** Clean up, free any architecture-allocated memory.
  231. * \param arch architecture
  232. */
  233. void yasm_arch_destroy(/*@only@*/ yasm_arch *arch);
  234. /** Get architecture's active machine name.
  235. * \param arch architecture
  236. * \return Active machine name.
  237. */
  238. const char *yasm_arch_get_machine(const yasm_arch *arch);
  239. /** Get architecture's active address size, in bits.
  240. * \param arch architecture
  241. * \return Active address size (in bits).
  242. */
  243. unsigned int yasm_arch_get_address_size(const yasm_arch *arch);
  244. /** Set any arch-specific variables. For example, "mode_bits" in x86.
  245. * \param arch architecture
  246. * \param var variable name
  247. * \param val value to set
  248. * \return Zero on success, non-zero on failure (variable does not exist).
  249. */
  250. int yasm_arch_set_var(yasm_arch *arch, const char *var, unsigned long val);
  251. /** Check an generic identifier to see if it matches architecture specific
  252. * names for instructions or instruction prefixes. Unrecognized identifiers
  253. * should return #YASM_ARCH_NOTINSNPREFIX so they can be treated as normal
  254. * symbols. Any additional data beyond just the type (almost always necessary)
  255. * should be returned into the space provided by the data parameter.
  256. * \param arch architecture
  257. * \param id identifier as in the input file
  258. * \param id_len length of id string
  259. * \param line virtual line
  260. * \param bc for instructions, yasm_insn-based bytecode is returned
  261. * (and NULL otherwise)
  262. * \param prefix for prefixes, yasm_arch-specific value is returned
  263. * (and 0 otherwise)
  264. * \return Identifier type (#YASM_ARCH_NOTINSNPREFIX if unrecognized)
  265. */
  266. yasm_arch_insnprefix yasm_arch_parse_check_insnprefix
  267. (yasm_arch *arch, const char *id, size_t id_len, unsigned long line,
  268. /*@out@*/ /*@only@*/ yasm_bytecode **bc, /*@out@*/ uintptr_t *prefix);
  269. /** Check an generic identifier to see if it matches architecture specific
  270. * names for registers or target modifiers. Unrecognized identifiers should
  271. * return #YASM_ARCH_NOTREGTMOD. Any additional data beyond just the type
  272. * (almost always necessary) should be returned into the space provided by the
  273. * data parameter.
  274. * \param arch architecture
  275. * \param id identifier as in the input file
  276. * \param id_len length of id string
  277. * \param data extra identification information (yasm_arch-specific)
  278. * [output]
  279. * \return Identifier type (#YASM_ARCH_NOTREGTMOD if unrecognized)
  280. */
  281. yasm_arch_regtmod yasm_arch_parse_check_regtmod
  282. (yasm_arch *arch, const char *id, size_t id_len,
  283. /*@out@*/ uintptr_t *data);
  284. /** Get NOP fill patterns for 1-15 bytes of fill.
  285. * \param arch architecture
  286. * \return 16-entry array of arrays; [0] is unused, [1] - [15] point to arrays
  287. * of 1-15 bytes (respectively) in length.
  288. */
  289. const unsigned char **yasm_arch_get_fill(const yasm_arch *arch);
  290. /** Output #yasm_floatnum to buffer. Puts the value into the least
  291. * significant bits of the destination, or may be shifted into more
  292. * significant bits by the shift parameter. The destination bits are
  293. * cleared before being set.
  294. * Architecture-specific because of endianness.
  295. * \param arch architecture
  296. * \param flt floating point value
  297. * \param buf buffer to write into
  298. * \param destsize destination size (in bytes)
  299. * \param valsize size (in bits)
  300. * \param shift left shift (in bits)
  301. * \param warn enables standard overflow/underflow warnings
  302. * \return Nonzero on error.
  303. */
  304. int yasm_arch_floatnum_tobytes(yasm_arch *arch, const yasm_floatnum *flt,
  305. unsigned char *buf, size_t destsize,
  306. size_t valsize, size_t shift, int warn);
  307. /** Output #yasm_intnum to buffer. Puts the value into the least
  308. * significant bits of the destination, or may be shifted into more
  309. * significant bits by the shift parameter. The destination bits are
  310. * cleared before being set.
  311. * \param arch architecture
  312. * \param intn integer value
  313. * \param buf buffer to write into
  314. * \param destsize destination size (in bytes)
  315. * \param valsize size (in bits)
  316. * \param shift left shift (in bits); may be negative to specify right
  317. * shift (standard warnings include truncation to boundary)
  318. * \param bc bytecode being output ("parent" of value)
  319. * \param warn enables standard warnings (value doesn't fit into
  320. * valsize bits)
  321. * \return Nonzero on error.
  322. */
  323. int yasm_arch_intnum_tobytes(yasm_arch *arch, const yasm_intnum *intn,
  324. unsigned char *buf, size_t destsize,
  325. size_t valsize, int shift,
  326. const yasm_bytecode *bc, int warn);
  327. /** Get the equivalent size of a register in bits.
  328. * \param arch architecture
  329. * \param reg register
  330. * \return 0 if there is no suitable equivalent size, otherwise the size.
  331. */
  332. unsigned int yasm_arch_get_reg_size(yasm_arch *arch, uintptr_t reg);
  333. /** Get a specific register of a register group, based on the register
  334. * group and the index within the group.
  335. * \param arch architecture
  336. * \param reggroup register group
  337. * \param regindex register index
  338. * \return 0 if regindex is not valid for that register group, otherwise the
  339. * specific register value.
  340. */
  341. uintptr_t yasm_arch_reggroup_get_reg(yasm_arch *arch, uintptr_t reggroup,
  342. unsigned long regindex);
  343. /** Print a register. For debugging purposes.
  344. * \param arch architecture
  345. * \param reg register
  346. * \param f file
  347. */
  348. void yasm_arch_reg_print(yasm_arch *arch, uintptr_t reg, FILE *f);
  349. /** Print a segment register. For debugging purposes.
  350. * \param arch architecture
  351. * \param segreg segment register
  352. * \param f file
  353. */
  354. void yasm_arch_segreg_print(yasm_arch *arch, uintptr_t segreg, FILE *f);
  355. /** Create an effective address from an expression.
  356. * \param arch architecture
  357. * \param e expression (kept, do not delete)
  358. * \return Newly allocated effective address.
  359. */
  360. yasm_effaddr *yasm_arch_ea_create(yasm_arch *arch, /*@keep@*/ yasm_expr *e);
  361. /** Delete (free allocated memory for) an effective address.
  362. * \param arch architecture
  363. * \param ea effective address (only pointer to it).
  364. */
  365. void yasm_arch_ea_destroy(yasm_arch *arch, /*@only@*/ yasm_effaddr *ea);
  366. /** Print an effective address. For debugging purposes.
  367. * \param arch architecture
  368. * \param ea effective address
  369. * \param f file
  370. * \param indent_level indentation level
  371. */
  372. void yasm_arch_ea_print(const yasm_arch *arch, const yasm_effaddr *ea,
  373. FILE *f, int indent_level);
  374. /** Create a bytecode that represents a single empty (0 length) instruction.
  375. * This is used for handling solitary prefixes.
  376. * \param arch architecture
  377. * \param line virtual line (from yasm_linemap)
  378. * \return Newly allocated bytecode.
  379. */
  380. /*@only@*/ yasm_bytecode *yasm_arch_create_empty_insn(yasm_arch *arch,
  381. unsigned long line);
  382. #ifndef YASM_DOXYGEN
  383. /* Inline macro implementations for arch functions */
  384. #define yasm_arch_name(arch) \
  385. (((yasm_arch_base *)arch)->module->name)
  386. #define yasm_arch_keyword(arch) \
  387. (((yasm_arch_base *)arch)->module->keyword)
  388. #define yasm_arch_wordsize(arch) \
  389. (((yasm_arch_base *)arch)->module->wordsize)
  390. #define yasm_arch_min_insn_len(arch) \
  391. (((yasm_arch_base *)arch)->module->min_insn_len)
  392. #define yasm_arch_create(module, machine, parser, error) \
  393. module->create(machine, parser, error)
  394. #define yasm_arch_destroy(arch) \
  395. ((yasm_arch_base *)arch)->module->destroy(arch)
  396. #define yasm_arch_get_machine(arch) \
  397. ((yasm_arch_base *)arch)->module->get_machine(arch)
  398. #define yasm_arch_get_address_size(arch) \
  399. ((yasm_arch_base *)arch)->module->get_address_size(arch)
  400. #define yasm_arch_set_var(arch, var, val) \
  401. ((yasm_arch_base *)arch)->module->set_var(arch, var, val)
  402. #define yasm_arch_parse_check_insnprefix(arch, id, id_len, line, bc, prefix) \
  403. ((yasm_arch_base *)arch)->module->parse_check_insnprefix \
  404. (arch, id, id_len, line, bc, prefix)
  405. #define yasm_arch_parse_check_regtmod(arch, id, id_len, data) \
  406. ((yasm_arch_base *)arch)->module->parse_check_regtmod \
  407. (arch, id, id_len, data)
  408. #define yasm_arch_get_fill(arch) \
  409. ((yasm_arch_base *)arch)->module->get_fill(arch)
  410. #define yasm_arch_floatnum_tobytes(arch, flt, buf, destsize, valsize, shift, \
  411. warn) \
  412. ((yasm_arch_base *)arch)->module->floatnum_tobytes \
  413. (arch, flt, buf, destsize, valsize, shift, warn)
  414. #define yasm_arch_intnum_tobytes(arch, intn, buf, destsize, valsize, shift, \
  415. bc, warn) \
  416. ((yasm_arch_base *)arch)->module->intnum_tobytes \
  417. (arch, intn, buf, destsize, valsize, shift, bc, warn)
  418. #define yasm_arch_get_reg_size(arch, reg) \
  419. ((yasm_arch_base *)arch)->module->get_reg_size(arch, reg)
  420. #define yasm_arch_reggroup_get_reg(arch, regg, regi) \
  421. ((yasm_arch_base *)arch)->module->reggroup_get_reg(arch, regg, regi)
  422. #define yasm_arch_reg_print(arch, reg, f) \
  423. ((yasm_arch_base *)arch)->module->reg_print(arch, reg, f)
  424. #define yasm_arch_segreg_print(arch, segreg, f) \
  425. ((yasm_arch_base *)arch)->module->segreg_print(arch, segreg, f)
  426. #define yasm_arch_ea_create(arch, e) \
  427. ((yasm_arch_base *)arch)->module->ea_create(arch, e)
  428. #define yasm_arch_ea_destroy(arch, ea) \
  429. ((yasm_arch_base *)arch)->module->ea_destroy(ea)
  430. #define yasm_arch_ea_print(arch, ea, f, i) \
  431. ((yasm_arch_base *)arch)->module->ea_print(ea, f, i)
  432. #define yasm_arch_create_empty_insn(arch, line) \
  433. ((yasm_arch_base *)arch)->module->create_empty_insn(arch, line)
  434. #endif
  435. #endif