145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/** 245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \file libyasm/expr.h 345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \brief YASM expression interface. 445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \license 645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Copyright (C) 2001-2007 Michael Urman, Peter Johnson 745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Redistribution and use in source and binary forms, with or without 945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * modification, are permitted provided that the following conditions 1045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * are met: 1145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * - Redistributions of source code must retain the above copyright 1245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * notice, this list of conditions and the following disclaimer. 1345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * - Redistributions in binary form must reproduce the above copyright 1445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * notice, this list of conditions and the following disclaimer in the 1545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * documentation and/or other materials provided with the distribution. 1645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * 1745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS'' 1845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 1945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE 2145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 2245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 2345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 2445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 2545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 2645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 2745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * POSSIBILITY OF SUCH DAMAGE. 2845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \endlicense 2945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 3045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#ifndef YASM_EXPR_H 3145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#define YASM_EXPR_H 3245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 3345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#ifndef YASM_LIB_DECL 3445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#define YASM_LIB_DECL 3545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#endif 3645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 3745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/** Type of an expression item. Types are listed in canonical sorting order. 3845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * See expr_order_terms(). 3945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Note #YASM_EXPR_PRECBC must be used carefully (in a-b pairs), as only 4045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * symrecs can become the relative term in a #yasm_value. 4145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 4245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgtypedef enum yasm_expr__type { 4345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org YASM_EXPR_NONE = 0, /**< Nothing */ 4445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org YASM_EXPR_REG = 1<<0, /**< Register */ 4545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org YASM_EXPR_INT = 1<<1, /**< Integer value */ 4645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org YASM_EXPR_SUBST = 1<<2, /**< Substitution placeholder */ 4745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org YASM_EXPR_FLOAT = 1<<3, /**< Floating point value */ 4845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org YASM_EXPR_SYM = 1<<4, /**< Symbol */ 4945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org YASM_EXPR_PRECBC = 1<<5,/**< Direct bytecode ref (rather than via sym) */ 5045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org YASM_EXPR_EXPR = 1<<6 /**< Subexpression */ 5145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} yasm_expr__type; 5245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 5345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/** Expression item. */ 5445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgtypedef struct yasm_expr__item { 5545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_expr__type type; /**< Type */ 5645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 5745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /** Expression item data. Correct value depends on type. */ 5845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org union { 5945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_bytecode *precbc; /**< Direct bytecode ref (YASM_EXPR_PRECBC) */ 6045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_symrec *sym; /**< Symbol (YASM_EXPR_SYM) */ 6145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_expr *expn; /**< Subexpression (YASM_EXPR_EXPR) */ 6245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_intnum *intn; /**< Integer value (YASM_EXPR_INT) */ 6345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_floatnum *flt; /**< Floating point value (YASM_EXPR_FLOAT) */ 6445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org uintptr_t reg; /**< Register (YASM_EXPR_REG) */ 6545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unsigned int subst; /**< Subst placeholder (YASM_EXPR_SUBST) */ 6645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org } data; 6745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org} yasm_expr__item; 6845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 6945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/** Expression. */ 7045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgstruct yasm_expr { 7145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_expr_op op; /**< Operation. */ 7245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org unsigned long line; /**< Line number where expression was defined. */ 7345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int numterms; /**< Number of terms in the expression. */ 7445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 7545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /** Terms of the expression. Structure may be extended to include more 7645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * terms, as some operations may allow more than two operand terms 7745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * (ADD, MUL, OR, AND, XOR). 7845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 7945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_expr__item terms[2]; 8045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org}; 8145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 8245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/** Create a new expression e=a op b. 8345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param op operation 8445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param a expression item a 8545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param b expression item b (optional depending on op) 8645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param line virtual line (where expression defined) 8745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \return Newly allocated expression. 8845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 8945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgYASM_LIB_DECL 9045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/*@only@*/ yasm_expr *yasm_expr_create 9145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org (yasm_expr_op op, /*@only@*/ yasm_expr__item *a, 9245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@only@*/ /*@null@*/ yasm_expr__item *b, unsigned long line); 9345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 9445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/** Create a new preceding-bytecode expression item. 9545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param precbc preceding bytecode 9645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \return Newly allocated expression item. 9745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 9845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgYASM_LIB_DECL 9945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/*@only@*/ yasm_expr__item *yasm_expr_precbc(/*@keep@*/ yasm_bytecode *precbc); 10045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 10145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/** Create a new symbol expression item. 10245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param sym symbol 10345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \return Newly allocated expression item. 10445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 10545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgYASM_LIB_DECL 10645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/*@only@*/ yasm_expr__item *yasm_expr_sym(/*@keep@*/ yasm_symrec *sym); 10745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 10845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/** Create a new expression expression item. 10945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param e expression 11045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \return Newly allocated expression item. 11145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 11245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgYASM_LIB_DECL 11345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/*@only@*/ yasm_expr__item *yasm_expr_expr(/*@keep@*/ yasm_expr *e); 11445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 11545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/** Create a new intnum expression item. 11645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param intn intnum 11745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \return Newly allocated expression item. 11845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 11945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgYASM_LIB_DECL 12045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/*@only@*/ yasm_expr__item *yasm_expr_int(/*@keep@*/ yasm_intnum *intn); 12145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 12245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/** Create a new floatnum expression item. 12345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param flt floatnum 12445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \return Newly allocated expression item. 12545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 12645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgYASM_LIB_DECL 12745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/*@only@*/ yasm_expr__item *yasm_expr_float(/*@keep@*/ yasm_floatnum *flt); 12845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 12945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/** Create a new register expression item. 13045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param reg register 13145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \return Newly allocated expression item. 13245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 13345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgYASM_LIB_DECL 13445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/*@only@*/ yasm_expr__item *yasm_expr_reg(uintptr_t reg); 13545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 13645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/** Create a new expression tree e=l op r. 13745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param l expression for left side of new expression 13845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param o operation 13945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param r expression for right side of new expression 14045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param i line index 14145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \return Newly allocated expression. 14245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 14345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#define yasm_expr_create_tree(l,o,r,i) \ 14445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_expr_create ((o), yasm_expr_expr(l), yasm_expr_expr(r), i) 14545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 14645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/** Create a new expression branch e=op r. 14745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param o operation 14845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param r expression for right side of new expression 14945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param i line index 15045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \return Newly allocated expression. 15145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 15245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#define yasm_expr_create_branch(o,r,i) \ 15345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_expr_create ((o), yasm_expr_expr(r), (yasm_expr__item *)NULL, i) 15445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 15545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/** Create a new expression identity e=r. 15645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param r expression for identity within new expression 15745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param i line index 15845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \return Newly allocated expression. 15945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 16045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#define yasm_expr_create_ident(r,i) \ 16145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_expr_create (YASM_EXPR_IDENT, (r), (yasm_expr__item *)NULL, i) 16245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 16345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/** Duplicate an expression. 16445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param e expression 16545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \return Newly allocated expression identical to e. 16645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 16745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_expr *yasm_expr_copy(const yasm_expr *e); 16845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#ifndef YASM_DOXYGEN 16945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#define yasm_expr_copy(e) yasm_expr__copy_except(e, -1) 17045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#endif 17145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 17245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/** Destroy (free allocated memory for) an expression. 17345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param e expression 17445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 17545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgYASM_LIB_DECL 17645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgvoid yasm_expr_destroy(/*@only@*/ /*@null@*/ yasm_expr *e); 17745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 17845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/** Determine if an expression is a specified operation (at the top level). 17945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param e expression 18045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param op operator 18145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \return Nonzero if the expression was the specified operation at the top 18245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * level, zero otherwise. 18345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 18445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgYASM_LIB_DECL 18545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgint yasm_expr_is_op(const yasm_expr *e, yasm_expr_op op); 18645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 18745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/** Extra transformation function for yasm_expr__level_tree(). 18845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param e expression being simplified 18945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param d data provided as expr_xform_extra_data to 19045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * yasm_expr__level_tree() 19145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \return Transformed e. 19245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 19345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgtypedef /*@only@*/ yasm_expr * (*yasm_expr_xform_func) 19445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org (/*@returned@*/ /*@only@*/ yasm_expr *e, /*@null@*/ void *d); 19545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 19645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/** Level an entire expression tree. 19745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \internal 19845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param e expression 19945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param fold_const enable constant folding if nonzero 20045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param simplify_ident simplify identities 20145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param simplify_reg_mul simplify REG*1 identities 20245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param calc_bc_dist nonzero if distances between bytecodes should be 20345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * calculated, 0 if they should be left intact 20445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param expr_xform_extra extra transformation function 20545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param expr_xform_extra_data data to pass to expr_xform_extra 20645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \return Leveled expression. 20745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 20845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgYASM_LIB_DECL 20945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/*@only@*/ /*@null@*/ yasm_expr *yasm_expr__level_tree 21045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org (/*@returned@*/ /*@only@*/ /*@null@*/ yasm_expr *e, int fold_const, 21145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int simplify_ident, int simplify_reg_mul, int calc_bc_dist, 21245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@null@*/ yasm_expr_xform_func expr_xform_extra, 21345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org /*@null@*/ void *expr_xform_extra_data); 21445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 21545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/** Simplify an expression as much as possible. Eliminates extraneous 21645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * branches and simplifies integer-only subexpressions. Simplified version 21745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * of yasm_expr__level_tree(). 21845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param e expression 21945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param cbd if distance between bytecodes should be calculated 22045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \return Simplified expression. 22145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 22245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#define yasm_expr_simplify(e, cbd) \ 22345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_expr__level_tree(e, 1, 1, 1, cbd, NULL, NULL) 22445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 22545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/** Extract the segment portion of an expression containing SEG:OFF, leaving 22645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * the offset. 22745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param ep expression (pointer to) 22845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \return NULL if unable to extract a segment (expr does not contain a 22945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * YASM_EXPR_SEGOFF operator), otherwise the segment expression. 23045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * The input expression is modified such that on return, it's the 23145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * offset expression. 23245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 23345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgYASM_LIB_DECL 23445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/*@only@*/ /*@null@*/ yasm_expr *yasm_expr_extract_deep_segoff(yasm_expr **ep); 23545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 23645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/** Extract the segment portion of a SEG:OFF expression, leaving the offset. 23745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param ep expression (pointer to) 23845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \return NULL if unable to extract a segment (YASM_EXPR_SEGOFF not the 23945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * top-level operator), otherwise the segment expression. The input 24045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * expression is modified such that on return, it's the offset 24145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * expression. 24245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 24345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgYASM_LIB_DECL 24445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/*@only@*/ /*@null@*/ yasm_expr *yasm_expr_extract_segoff(yasm_expr **ep); 24545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 24645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/** Extract the right portion (y) of a x WRT y expression, leaving the left 24745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * portion (x). 24845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param ep expression (pointer to) 24945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \return NULL if unable to extract (YASM_EXPR_WRT not the top-level 25045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * operator), otherwise the right side of the WRT expression. The 25145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * input expression is modified such that on return, it's the left side 25245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * of the WRT expression. 25345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 25445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgYASM_LIB_DECL 25545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/*@only@*/ /*@null@*/ yasm_expr *yasm_expr_extract_wrt(yasm_expr **ep); 25645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 25745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/** Get the integer value of an expression if it's just an integer. 25845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param ep expression (pointer to) 25945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param calc_bc_dist nonzero if distances between bytecodes should be 26045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * calculated, 0 if NULL should be returned in this case 26145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \return NULL if the expression is too complex (contains anything other than 26245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * integers, ie floats, non-valued labels, registers); otherwise the 26345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * intnum value of the expression. 26445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 26545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgYASM_LIB_DECL 26645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/*@dependent@*/ /*@null@*/ yasm_intnum *yasm_expr_get_intnum 26745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org (yasm_expr **ep, int calc_bc_dist); 26845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 26945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/** Get the symbol value of an expression if it's just a symbol. 27045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param ep expression (pointer to) 27145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param simplify if nonzero, simplify the expression first 27245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \return NULL if the expression is too complex; otherwise the symbol value of 27345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * the expression. 27445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 27545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgYASM_LIB_DECL 27645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/*@dependent@*/ /*@null@*/ const yasm_symrec *yasm_expr_get_symrec 27745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org (yasm_expr **ep, int simplify); 27845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 27945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/** Get the register value of an expression if it's just a register. 28045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param ep expression (pointer to) 28145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param simplify if nonzero, simplify the expression first 28245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \return NULL if the expression is too complex; otherwise the register value 28345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * of the expression. 28445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 28545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgYASM_LIB_DECL 28645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/*@dependent@*/ /*@null@*/ const uintptr_t *yasm_expr_get_reg 28745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org (yasm_expr **ep, int simplify); 28845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 28945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/** Print an expression. For debugging purposes. 29045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param e expression 29145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param f file 29245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 29345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgYASM_LIB_DECL 29445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgvoid yasm_expr_print(/*@null@*/ const yasm_expr *e, FILE *f); 29545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 29645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/** Return the size of an expression, if the user provided it 29745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param e expression 29845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 29945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgunsigned int yasm_expr_size(const yasm_expr *e); 30045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 30145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/** Return the segment of an expression, if the user provided it 30245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param e expression 30345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 30445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgconst char *yasm_expr_segment(const yasm_expr *e); 30545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 30645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/** Traverse over expression tree in order (const version). 30745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Calls func for each leaf (non-operation). 30845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param e expression 30945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param d data passed to each call to func 31045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param func callback function 31145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \return Stops early (and returns 1) if func returns 1. 31245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Otherwise returns 0. 31345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 31445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgYASM_LIB_DECL 31545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgint yasm_expr__traverse_leaves_in_const 31645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org (const yasm_expr *e, /*@null@*/ void *d, 31745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int (*func) (/*@null@*/ const yasm_expr__item *ei, /*@null@*/ void *d)); 31845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 31945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/** Traverse over expression tree in order. 32045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Calls func for each leaf (non-operation). 32145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param e expression 32245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param d data passed to each call to func 32345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param func callback function 32445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \return Stops early (and returns 1) if func returns 1. 32545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Otherwise returns 0. 32645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 32745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgYASM_LIB_DECL 32845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgint yasm_expr__traverse_leaves_in 32945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org (yasm_expr *e, /*@null@*/ void *d, 33045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org int (*func) (/*@null@*/ yasm_expr__item *ei, /*@null@*/ void *d)); 33145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 33245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/** Reorder terms of e into canonical order. Only reorders if reordering 33345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * doesn't change meaning of expression. (eg, doesn't reorder SUB). 33445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Canonical order: REG, INT, FLOAT, SYM, EXPR. 33545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Multiple terms of a single type are kept in the same order as in 33645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * the original expression. 33745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param e expression 33845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \note Only performs reordering on *one* level (no recursion). 33945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 34045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgYASM_LIB_DECL 34145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgvoid yasm_expr__order_terms(yasm_expr *e); 34245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 34345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/** Copy entire expression EXCEPT for index "except" at *top level only*. 34445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param e expression 34545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param except term index not to copy; -1 to copy all terms 34645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \return Newly allocated copy of expression. 34745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 34845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgYASM_LIB_DECL 34945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgyasm_expr *yasm_expr__copy_except(const yasm_expr *e, int except); 35045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 35145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/** Test if expression contains an item. Searches recursively into 35245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * subexpressions. 35345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param e expression 35445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param t type of item to look for 35545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \return Nonzero if expression contains an item of type t, zero if not. 35645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 35745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgYASM_LIB_DECL 35845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgint yasm_expr__contains(const yasm_expr *e, yasm_expr__type t); 35945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 36045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/** Transform symrec-symrec terms in expression into #YASM_EXPR_SUBST items. 36145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * Calls the callback function for each symrec-symrec term. 36245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param ep expression (pointer to) 36345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param cbd callback data passed to callback function 36445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param callback callback function: given subst index for bytecode 36545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * pair, bytecode pair (bc2-bc1), and cbd (callback data) 36645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \return Number of transformations made. 36745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 36845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgYASM_LIB_DECL 36945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgint yasm_expr__bc_dist_subst(yasm_expr **ep, void *cbd, 37045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org void (*callback) (unsigned int subst, 37145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_bytecode *precbc, 37245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org yasm_bytecode *precbc2, 37345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org void *cbd)); 37445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 37545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org/** Substitute items into expr YASM_EXPR_SUBST items (by index). Items are 37645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * copied, so caller is responsible for freeing array of items. 37745afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param e expression 37845afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param num_items number of items in items array 37945afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \param items items array 38045afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org * \return 1 on error (index out of range). 38145afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org */ 38245afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgYASM_LIB_DECL 38345afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.orgint yasm_expr__subst(yasm_expr *e, unsigned int num_items, 38445afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org const yasm_expr__item *items); 38545afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org 38645afe016bed87b9c6946184709058b39ede3f77ajwong@chromium.org#endif 387