expr.h 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388
  1. /**
  2. * \file libyasm/expr.h
  3. * \brief YASM expression interface.
  4. *
  5. * \license
  6. * Copyright (C) 2001-2007 Michael Urman, 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_EXPR_H
  31. #define YASM_EXPR_H
  32. #ifndef YASM_LIB_DECL
  33. #define YASM_LIB_DECL
  34. #endif
  35. /** Type of an expression item. Types are listed in canonical sorting order.
  36. * See expr_order_terms().
  37. * Note #YASM_EXPR_PRECBC must be used carefully (in a-b pairs), as only
  38. * symrecs can become the relative term in a #yasm_value.
  39. */
  40. typedef enum yasm_expr__type {
  41. YASM_EXPR_NONE = 0, /**< Nothing */
  42. YASM_EXPR_REG = 1<<0, /**< Register */
  43. YASM_EXPR_INT = 1<<1, /**< Integer value */
  44. YASM_EXPR_SUBST = 1<<2, /**< Substitution placeholder */
  45. YASM_EXPR_FLOAT = 1<<3, /**< Floating point value */
  46. YASM_EXPR_SYM = 1<<4, /**< Symbol */
  47. YASM_EXPR_PRECBC = 1<<5,/**< Direct bytecode ref (rather than via sym) */
  48. YASM_EXPR_EXPR = 1<<6 /**< Subexpression */
  49. } yasm_expr__type;
  50. /** Expression item. */
  51. typedef struct yasm_expr__item {
  52. yasm_expr__type type; /**< Type */
  53. /** Expression item data. Correct value depends on type. */
  54. union {
  55. yasm_bytecode *precbc; /**< Direct bytecode ref (YASM_EXPR_PRECBC) */
  56. yasm_symrec *sym; /**< Symbol (YASM_EXPR_SYM) */
  57. yasm_expr *expn; /**< Subexpression (YASM_EXPR_EXPR) */
  58. yasm_intnum *intn; /**< Integer value (YASM_EXPR_INT) */
  59. yasm_floatnum *flt; /**< Floating point value (YASM_EXPR_FLOAT) */
  60. uintptr_t reg; /**< Register (YASM_EXPR_REG) */
  61. unsigned int subst; /**< Subst placeholder (YASM_EXPR_SUBST) */
  62. } data;
  63. } yasm_expr__item;
  64. /** Expression. */
  65. struct yasm_expr {
  66. yasm_expr_op op; /**< Operation. */
  67. unsigned long line; /**< Line number where expression was defined. */
  68. int numterms; /**< Number of terms in the expression. */
  69. /** Terms of the expression. Structure may be extended to include more
  70. * terms, as some operations may allow more than two operand terms
  71. * (ADD, MUL, OR, AND, XOR).
  72. */
  73. yasm_expr__item terms[2];
  74. };
  75. /** Create a new expression e=a op b.
  76. * \param op operation
  77. * \param a expression item a
  78. * \param b expression item b (optional depending on op)
  79. * \param line virtual line (where expression defined)
  80. * \return Newly allocated expression.
  81. */
  82. YASM_LIB_DECL
  83. /*@only@*/ yasm_expr *yasm_expr_create
  84. (yasm_expr_op op, /*@only@*/ yasm_expr__item *a,
  85. /*@only@*/ /*@null@*/ yasm_expr__item *b, unsigned long line);
  86. /** Create a new preceding-bytecode expression item.
  87. * \param precbc preceding bytecode
  88. * \return Newly allocated expression item.
  89. */
  90. YASM_LIB_DECL
  91. /*@only@*/ yasm_expr__item *yasm_expr_precbc(/*@keep@*/ yasm_bytecode *precbc);
  92. /** Create a new symbol expression item.
  93. * \param sym symbol
  94. * \return Newly allocated expression item.
  95. */
  96. YASM_LIB_DECL
  97. /*@only@*/ yasm_expr__item *yasm_expr_sym(/*@keep@*/ yasm_symrec *sym);
  98. /** Create a new expression expression item.
  99. * \param e expression
  100. * \return Newly allocated expression item.
  101. */
  102. YASM_LIB_DECL
  103. /*@only@*/ yasm_expr__item *yasm_expr_expr(/*@keep@*/ yasm_expr *e);
  104. /** Create a new intnum expression item.
  105. * \param intn intnum
  106. * \return Newly allocated expression item.
  107. */
  108. YASM_LIB_DECL
  109. /*@only@*/ yasm_expr__item *yasm_expr_int(/*@keep@*/ yasm_intnum *intn);
  110. /** Create a new floatnum expression item.
  111. * \param flt floatnum
  112. * \return Newly allocated expression item.
  113. */
  114. YASM_LIB_DECL
  115. /*@only@*/ yasm_expr__item *yasm_expr_float(/*@keep@*/ yasm_floatnum *flt);
  116. /** Create a new register expression item.
  117. * \param reg register
  118. * \return Newly allocated expression item.
  119. */
  120. YASM_LIB_DECL
  121. /*@only@*/ yasm_expr__item *yasm_expr_reg(uintptr_t reg);
  122. /** Create a new expression tree e=l op r.
  123. * \param l expression for left side of new expression
  124. * \param o operation
  125. * \param r expression for right side of new expression
  126. * \param i line index
  127. * \return Newly allocated expression.
  128. */
  129. #define yasm_expr_create_tree(l,o,r,i) \
  130. yasm_expr_create ((o), yasm_expr_expr(l), yasm_expr_expr(r), i)
  131. /** Create a new expression branch e=op r.
  132. * \param o operation
  133. * \param r expression for right side of new expression
  134. * \param i line index
  135. * \return Newly allocated expression.
  136. */
  137. #define yasm_expr_create_branch(o,r,i) \
  138. yasm_expr_create ((o), yasm_expr_expr(r), (yasm_expr__item *)NULL, i)
  139. /** Create a new expression identity e=r.
  140. * \param r expression for identity within new expression
  141. * \param i line index
  142. * \return Newly allocated expression.
  143. */
  144. #define yasm_expr_create_ident(r,i) \
  145. yasm_expr_create (YASM_EXPR_IDENT, (r), (yasm_expr__item *)NULL, i)
  146. /** Duplicate an expression.
  147. * \param e expression
  148. * \return Newly allocated expression identical to e.
  149. */
  150. yasm_expr *yasm_expr_copy(const yasm_expr *e);
  151. #ifndef YASM_DOXYGEN
  152. #define yasm_expr_copy(e) yasm_expr__copy_except(e, -1)
  153. #endif
  154. /** Destroy (free allocated memory for) an expression.
  155. * \param e expression
  156. */
  157. YASM_LIB_DECL
  158. void yasm_expr_destroy(/*@only@*/ /*@null@*/ yasm_expr *e);
  159. /** Determine if an expression is a specified operation (at the top level).
  160. * \param e expression
  161. * \param op operator
  162. * \return Nonzero if the expression was the specified operation at the top
  163. * level, zero otherwise.
  164. */
  165. YASM_LIB_DECL
  166. int yasm_expr_is_op(const yasm_expr *e, yasm_expr_op op);
  167. /** Extra transformation function for yasm_expr__level_tree().
  168. * \param e expression being simplified
  169. * \param d data provided as expr_xform_extra_data to
  170. * yasm_expr__level_tree()
  171. * \return Transformed e.
  172. */
  173. typedef /*@only@*/ yasm_expr * (*yasm_expr_xform_func)
  174. (/*@returned@*/ /*@only@*/ yasm_expr *e, /*@null@*/ void *d);
  175. /** Level an entire expression tree.
  176. * \internal
  177. * \param e expression
  178. * \param fold_const enable constant folding if nonzero
  179. * \param simplify_ident simplify identities
  180. * \param simplify_reg_mul simplify REG*1 identities
  181. * \param calc_bc_dist nonzero if distances between bytecodes should be
  182. * calculated, 0 if they should be left intact
  183. * \param expr_xform_extra extra transformation function
  184. * \param expr_xform_extra_data data to pass to expr_xform_extra
  185. * \return Leveled expression.
  186. */
  187. YASM_LIB_DECL
  188. /*@only@*/ /*@null@*/ yasm_expr *yasm_expr__level_tree
  189. (/*@returned@*/ /*@only@*/ /*@null@*/ yasm_expr *e, int fold_const,
  190. int simplify_ident, int simplify_reg_mul, int calc_bc_dist,
  191. /*@null@*/ yasm_expr_xform_func expr_xform_extra,
  192. /*@null@*/ void *expr_xform_extra_data);
  193. /** Simplify an expression as much as possible. Eliminates extraneous
  194. * branches and simplifies integer-only subexpressions. Simplified version
  195. * of yasm_expr__level_tree().
  196. * \param e expression
  197. * \param cbd if distance between bytecodes should be calculated
  198. * \return Simplified expression.
  199. */
  200. #define yasm_expr_simplify(e, cbd) \
  201. yasm_expr__level_tree(e, 1, 1, 1, cbd, NULL, NULL)
  202. /** Extract the segment portion of an expression containing SEG:OFF, leaving
  203. * the offset.
  204. * \param ep expression (pointer to)
  205. * \return NULL if unable to extract a segment (expr does not contain a
  206. * YASM_EXPR_SEGOFF operator), otherwise the segment expression.
  207. * The input expression is modified such that on return, it's the
  208. * offset expression.
  209. */
  210. YASM_LIB_DECL
  211. /*@only@*/ /*@null@*/ yasm_expr *yasm_expr_extract_deep_segoff(yasm_expr **ep);
  212. /** Extract the segment portion of a SEG:OFF expression, leaving the offset.
  213. * \param ep expression (pointer to)
  214. * \return NULL if unable to extract a segment (YASM_EXPR_SEGOFF not the
  215. * top-level operator), otherwise the segment expression. The input
  216. * expression is modified such that on return, it's the offset
  217. * expression.
  218. */
  219. YASM_LIB_DECL
  220. /*@only@*/ /*@null@*/ yasm_expr *yasm_expr_extract_segoff(yasm_expr **ep);
  221. /** Extract the right portion (y) of a x WRT y expression, leaving the left
  222. * portion (x).
  223. * \param ep expression (pointer to)
  224. * \return NULL if unable to extract (YASM_EXPR_WRT not the top-level
  225. * operator), otherwise the right side of the WRT expression. The
  226. * input expression is modified such that on return, it's the left side
  227. * of the WRT expression.
  228. */
  229. YASM_LIB_DECL
  230. /*@only@*/ /*@null@*/ yasm_expr *yasm_expr_extract_wrt(yasm_expr **ep);
  231. /** Get the integer value of an expression if it's just an integer.
  232. * \param ep expression (pointer to)
  233. * \param calc_bc_dist nonzero if distances between bytecodes should be
  234. * calculated, 0 if NULL should be returned in this case
  235. * \return NULL if the expression is too complex (contains anything other than
  236. * integers, ie floats, non-valued labels, registers); otherwise the
  237. * intnum value of the expression.
  238. */
  239. YASM_LIB_DECL
  240. /*@dependent@*/ /*@null@*/ yasm_intnum *yasm_expr_get_intnum
  241. (yasm_expr **ep, int calc_bc_dist);
  242. /** Get the symbol value of an expression if it's just a symbol.
  243. * \param ep expression (pointer to)
  244. * \param simplify if nonzero, simplify the expression first
  245. * \return NULL if the expression is too complex; otherwise the symbol value of
  246. * the expression.
  247. */
  248. YASM_LIB_DECL
  249. /*@dependent@*/ /*@null@*/ const yasm_symrec *yasm_expr_get_symrec
  250. (yasm_expr **ep, int simplify);
  251. /** Get the register value of an expression if it's just a register.
  252. * \param ep expression (pointer to)
  253. * \param simplify if nonzero, simplify the expression first
  254. * \return NULL if the expression is too complex; otherwise the register value
  255. * of the expression.
  256. */
  257. YASM_LIB_DECL
  258. /*@dependent@*/ /*@null@*/ const uintptr_t *yasm_expr_get_reg
  259. (yasm_expr **ep, int simplify);
  260. /** Print an expression. For debugging purposes.
  261. * \param e expression
  262. * \param f file
  263. */
  264. YASM_LIB_DECL
  265. void yasm_expr_print(/*@null@*/ const yasm_expr *e, FILE *f);
  266. /** Return the size of an expression, if the user provided it
  267. * \param e expression
  268. */
  269. YASM_LIB_DECL
  270. unsigned int yasm_expr_size(const yasm_expr *e);
  271. /** Return the segment of an expression, if the user provided it
  272. * \param e expression
  273. */
  274. YASM_LIB_DECL
  275. const char *yasm_expr_segment(const yasm_expr *e);
  276. /** Traverse over expression tree in order (const version).
  277. * Calls func for each leaf (non-operation).
  278. * \param e expression
  279. * \param d data passed to each call to func
  280. * \param func callback function
  281. * \return Stops early (and returns 1) if func returns 1.
  282. * Otherwise returns 0.
  283. */
  284. YASM_LIB_DECL
  285. int yasm_expr__traverse_leaves_in_const
  286. (const yasm_expr *e, /*@null@*/ void *d,
  287. int (*func) (/*@null@*/ const yasm_expr__item *ei, /*@null@*/ void *d));
  288. /** Traverse over expression tree in order.
  289. * Calls func for each leaf (non-operation).
  290. * \param e expression
  291. * \param d data passed to each call to func
  292. * \param func callback function
  293. * \return Stops early (and returns 1) if func returns 1.
  294. * Otherwise returns 0.
  295. */
  296. YASM_LIB_DECL
  297. int yasm_expr__traverse_leaves_in
  298. (yasm_expr *e, /*@null@*/ void *d,
  299. int (*func) (/*@null@*/ yasm_expr__item *ei, /*@null@*/ void *d));
  300. /** Reorder terms of e into canonical order. Only reorders if reordering
  301. * doesn't change meaning of expression. (eg, doesn't reorder SUB).
  302. * Canonical order: REG, INT, FLOAT, SYM, EXPR.
  303. * Multiple terms of a single type are kept in the same order as in
  304. * the original expression.
  305. * \param e expression
  306. * \note Only performs reordering on *one* level (no recursion).
  307. */
  308. YASM_LIB_DECL
  309. void yasm_expr__order_terms(yasm_expr *e);
  310. /** Copy entire expression EXCEPT for index "except" at *top level only*.
  311. * \param e expression
  312. * \param except term index not to copy; -1 to copy all terms
  313. * \return Newly allocated copy of expression.
  314. */
  315. YASM_LIB_DECL
  316. yasm_expr *yasm_expr__copy_except(const yasm_expr *e, int except);
  317. /** Test if expression contains an item. Searches recursively into
  318. * subexpressions.
  319. * \param e expression
  320. * \param t type of item to look for
  321. * \return Nonzero if expression contains an item of type t, zero if not.
  322. */
  323. YASM_LIB_DECL
  324. int yasm_expr__contains(const yasm_expr *e, yasm_expr__type t);
  325. /** Transform symrec-symrec terms in expression into #YASM_EXPR_SUBST items.
  326. * Calls the callback function for each symrec-symrec term.
  327. * \param ep expression (pointer to)
  328. * \param cbd callback data passed to callback function
  329. * \param callback callback function: given subst index for bytecode
  330. * pair, bytecode pair (bc2-bc1), and cbd (callback data)
  331. * \return Number of transformations made.
  332. */
  333. YASM_LIB_DECL
  334. int yasm_expr__bc_dist_subst(yasm_expr **ep, void *cbd,
  335. void (*callback) (unsigned int subst,
  336. yasm_bytecode *precbc,
  337. yasm_bytecode *precbc2,
  338. void *cbd));
  339. /** Substitute items into expr YASM_EXPR_SUBST items (by index). Items are
  340. * copied, so caller is responsible for freeing array of items.
  341. * \param e expression
  342. * \param num_items number of items in items array
  343. * \param items items array
  344. * \return 1 on error (index out of range).
  345. */
  346. YASM_LIB_DECL
  347. int yasm_expr__subst(yasm_expr *e, unsigned int num_items,
  348. const yasm_expr__item *items);
  349. #endif