1 /* 2 * Expression handling 3 * 4 * Copyright (C) 2001-2007 Michael Urman, Peter Johnson 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND OTHER CONTRIBUTORS ``AS IS'' 16 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR OTHER CONTRIBUTORS BE 19 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 20 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 21 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 23 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 24 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25 * POSSIBILITY OF SUCH DAMAGE. 26 */ 27 #include "util.h" 28 29 #include "libyasm-stdint.h" 30 #include "coretype.h" 31 #include "bitvect.h" 32 33 #include "errwarn.h" 34 #include "intnum.h" 35 #include "floatnum.h" 36 #include "expr.h" 37 #include "symrec.h" 38 39 #include "bytecode.h" 40 #include "section.h" 41 42 #include "arch.h" 43 44 45 static /*@only@*/ yasm_expr *expr_level_op 46 (/*@returned@*/ /*@only@*/ yasm_expr *e, int fold_const, 47 int simplify_ident, int simplify_reg_mul); 48 static int expr_traverse_nodes_post(/*@null@*/ yasm_expr *e, 49 /*@null@*/ void *d, 50 int (*func) (/*@null@*/ yasm_expr *e, 51 /*@null@*/ void *d)); 52 static void expr_delete_term(yasm_expr__item *term, int recurse); 53 54 /* Bitmap of used items. We should really never need more than 2 at a time, 55 * so 31 is pretty much overkill. 56 */ 57 static unsigned long itempool_used = 0; 58 static yasm_expr__item itempool[31]; 59 60 /* allocate a new expression node, with children as defined. 61 * If it's a unary operator, put the element in left and set right=NULL. */ 62 /*@-compmempass@*/ 63 yasm_expr * 64 yasm_expr_create(yasm_expr_op op, yasm_expr__item *left, 65 yasm_expr__item *right, unsigned long line) 66 { 67 yasm_expr *ptr, *sube; 68 unsigned long z; 69 ptr = yasm_xmalloc(sizeof(yasm_expr)); 70 71 ptr->op = op; 72 ptr->numterms = 0; 73 ptr->terms[0].type = YASM_EXPR_NONE; 74 ptr->terms[1].type = YASM_EXPR_NONE; 75 if (left) { 76 ptr->terms[0] = *left; /* structure copy */ 77 z = (unsigned long)(left-itempool); 78 if (z>=31) 79 yasm_internal_error(N_("could not find expritem in pool")); 80 itempool_used &= ~(1<<z); 81 ptr->numterms++; 82 83 /* Search downward until we find something *other* than an 84 * IDENT, then bring it up to the current level. 85 */ 86 while (ptr->terms[0].type == YASM_EXPR_EXPR && 87 ptr->terms[0].data.expn->op == YASM_EXPR_IDENT) { 88 sube = ptr->terms[0].data.expn; 89 ptr->terms[0] = sube->terms[0]; /* structure copy */ 90 /*@-usereleased@*/ 91 yasm_xfree(sube); 92 /*@=usereleased@*/ 93 } 94 } else { 95 yasm_internal_error(N_("Right side of expression must exist")); 96 } 97 98 if (right) { 99 ptr->terms[1] = *right; /* structure copy */ 100 z = (unsigned long)(right-itempool); 101 if (z>=31) 102 yasm_internal_error(N_("could not find expritem in pool")); 103 itempool_used &= ~(1<<z); 104 ptr->numterms++; 105 106 /* Search downward until we find something *other* than an 107 * IDENT, then bring it up to the current level. 108 */ 109 while (ptr->terms[1].type == YASM_EXPR_EXPR && 110 ptr->terms[1].data.expn->op == YASM_EXPR_IDENT) { 111 sube = ptr->terms[1].data.expn; 112 ptr->terms[1] = sube->terms[0]; /* structure copy */ 113 /*@-usereleased@*/ 114 yasm_xfree(sube); 115 /*@=usereleased@*/ 116 } 117 } 118 119 ptr->line = line; 120 121 return expr_level_op(ptr, 1, 1, 0); 122 } 123 /*@=compmempass@*/ 124 125 /* helpers */ 126 static yasm_expr__item * 127 expr_get_item(void) 128 { 129 int z = 0; 130 unsigned long v = itempool_used & 0x7fffffff; 131 132 while (v & 1) { 133 v >>= 1; 134 z++; 135 } 136 if (z>=31) 137 yasm_internal_error(N_("too many expritems")); 138 itempool_used |= 1<<z; 139 return &itempool[z]; 140 } 141 142 yasm_expr__item * 143 yasm_expr_precbc(yasm_bytecode *precbc) 144 { 145 yasm_expr__item *e = expr_get_item(); 146 e->type = YASM_EXPR_PRECBC; 147 e->data.precbc = precbc; 148 return e; 149 } 150 151 yasm_expr__item * 152 yasm_expr_sym(yasm_symrec *s) 153 { 154 yasm_expr__item *e = expr_get_item(); 155 e->type = YASM_EXPR_SYM; 156 e->data.sym = s; 157 return e; 158 } 159 160 yasm_expr__item * 161 yasm_expr_expr(yasm_expr *x) 162 { 163 yasm_expr__item *e = expr_get_item(); 164 e->type = YASM_EXPR_EXPR; 165 e->data.expn = x; 166 return e; 167 } 168 169 yasm_expr__item * 170 yasm_expr_int(yasm_intnum *i) 171 { 172 yasm_expr__item *e = expr_get_item(); 173 e->type = YASM_EXPR_INT; 174 e->data.intn = i; 175 return e; 176 } 177 178 yasm_expr__item * 179 yasm_expr_float(yasm_floatnum *f) 180 { 181 yasm_expr__item *e = expr_get_item(); 182 e->type = YASM_EXPR_FLOAT; 183 e->data.flt = f; 184 return e; 185 } 186 187 yasm_expr__item * 188 yasm_expr_reg(uintptr_t reg) 189 { 190 yasm_expr__item *e = expr_get_item(); 191 e->type = YASM_EXPR_REG; 192 e->data.reg = reg; 193 return e; 194 } 195 196 /* Transforms instances of symrec-symrec [symrec+(-1*symrec)] into single 197 * expritems if possible. Uses a simple n^2 algorithm because n is usually 198 * quite small. Also works for precbc-precbc (or symrec-precbc, 199 * precbc-symrec). 200 */ 201 static /*@only@*/ yasm_expr * 202 expr_xform_bc_dist_base(/*@returned@*/ /*@only@*/ yasm_expr *e, 203 /*@null@*/ void *cbd, 204 int (*callback) (yasm_expr__item *ei, 205 yasm_bytecode *precbc, 206 yasm_bytecode *precbc2, 207 void *cbd)) 208 { 209 int i; 210 /*@dependent@*/ yasm_section *sect; 211 /*@dependent@*/ /*@null@*/ yasm_bytecode *precbc; 212 int numterms; 213 214 /* Handle symrec-symrec in ADD exprs by looking for (-1*symrec) and 215 * symrec term pairs (where both symrecs are in the same segment). 216 */ 217 if (e->op != YASM_EXPR_ADD) 218 return e; 219 220 for (i=0; i<e->numterms; i++) { 221 int j; 222 yasm_expr *sube; 223 yasm_intnum *intn; 224 yasm_symrec *sym = NULL; 225 /*@dependent@*/ yasm_section *sect2; 226 /*@dependent@*/ /*@null@*/ yasm_bytecode *precbc2; 227 228 /* First look for an (-1*symrec) term */ 229 if (e->terms[i].type != YASM_EXPR_EXPR) 230 continue; 231 sube = e->terms[i].data.expn; 232 if (sube->op != YASM_EXPR_MUL || sube->numterms != 2) 233 continue; 234 235 if (sube->terms[0].type == YASM_EXPR_INT && 236 (sube->terms[1].type == YASM_EXPR_SYM || 237 sube->terms[1].type == YASM_EXPR_PRECBC)) { 238 intn = sube->terms[0].data.intn; 239 if (sube->terms[1].type == YASM_EXPR_PRECBC) 240 precbc = sube->terms[1].data.precbc; 241 else 242 sym = sube->terms[1].data.sym; 243 } else if ((sube->terms[0].type == YASM_EXPR_SYM || 244 sube->terms[0].type == YASM_EXPR_PRECBC) && 245 sube->terms[1].type == YASM_EXPR_INT) { 246 if (sube->terms[0].type == YASM_EXPR_PRECBC) 247 precbc = sube->terms[0].data.precbc; 248 else 249 sym = sube->terms[0].data.sym; 250 intn = sube->terms[1].data.intn; 251 } else 252 continue; 253 254 if (!yasm_intnum_is_neg1(intn)) 255 continue; 256 257 if (sym && !yasm_symrec_get_label(sym, &precbc)) 258 continue; 259 sect2 = yasm_bc_get_section(precbc); 260 261 /* Now look for a symrec term in the same segment */ 262 for (j=0; j<e->numterms; j++) { 263 if (((e->terms[j].type == YASM_EXPR_SYM && 264 yasm_symrec_get_label(e->terms[j].data.sym, &precbc2)) || 265 (e->terms[j].type == YASM_EXPR_PRECBC && 266 (precbc2 = e->terms[j].data.precbc))) && 267 (sect = yasm_bc_get_section(precbc2)) && 268 sect == sect2 && 269 callback(&e->terms[j], precbc, precbc2, cbd)) { 270 /* Delete the matching (-1*symrec) term */ 271 yasm_expr_destroy(sube); 272 e->terms[i].type = YASM_EXPR_NONE; 273 break; /* stop looking for matching symrec term */ 274 } 275 } 276 } 277 278 /* Clean up any deleted (EXPR_NONE) terms */ 279 numterms = 0; 280 for (i=0; i<e->numterms; i++) { 281 if (e->terms[i].type != YASM_EXPR_NONE) 282 e->terms[numterms++] = e->terms[i]; /* structure copy */ 283 } 284 if (e->numterms != numterms) { 285 e->numterms = numterms; 286 e = yasm_xrealloc(e, sizeof(yasm_expr)+((numterms<2) ? 0 : 287 sizeof(yasm_expr__item)*(numterms-2))); 288 if (numterms == 1) 289 e->op = YASM_EXPR_IDENT; 290 } 291 292 return e; 293 } 294 295 static int 296 expr_xform_bc_dist_cb(yasm_expr__item *ei, yasm_bytecode *precbc, 297 yasm_bytecode *precbc2, /*@null@*/ void *d) 298 { 299 yasm_intnum *dist = yasm_calc_bc_dist(precbc, precbc2); 300 if (!dist) 301 return 0; 302 /* Change the term to an integer */ 303 ei->type = YASM_EXPR_INT; 304 ei->data.intn = dist; 305 return 1; 306 } 307 308 /* Transforms instances of symrec-symrec [symrec+(-1*symrec)] into integers if 309 * possible. 310 */ 311 static /*@only@*/ yasm_expr * 312 expr_xform_bc_dist(/*@returned@*/ /*@only@*/ yasm_expr *e) 313 { 314 return expr_xform_bc_dist_base(e, NULL, expr_xform_bc_dist_cb); 315 } 316 317 typedef struct bc_dist_subst_cbd { 318 void (*callback) (unsigned int subst, yasm_bytecode *precbc, 319 yasm_bytecode *precbc2, void *cbd); 320 void *cbd; 321 unsigned int subst; 322 } bc_dist_subst_cbd; 323 324 static int 325 expr_bc_dist_subst_cb(yasm_expr__item *ei, yasm_bytecode *precbc, 326 yasm_bytecode *precbc2, /*@null@*/ void *d) 327 { 328 bc_dist_subst_cbd *my_cbd = d; 329 assert(my_cbd != NULL); 330 /* Call higher-level callback */ 331 my_cbd->callback(my_cbd->subst, precbc, precbc2, my_cbd->cbd); 332 /* Change the term to an subst */ 333 ei->type = YASM_EXPR_SUBST; 334 ei->data.subst = my_cbd->subst; 335 my_cbd->subst++; 336 return 1; 337 } 338 339 static yasm_expr * 340 expr_xform_bc_dist_subst(yasm_expr *e, void *d) 341 { 342 return expr_xform_bc_dist_base(e, d, expr_bc_dist_subst_cb); 343 } 344 345 int 346 yasm_expr__bc_dist_subst(yasm_expr **ep, void *cbd, 347 void (*callback) (unsigned int subst, 348 yasm_bytecode *precbc, 349 yasm_bytecode *precbc2, 350 void *cbd)) 351 { 352 bc_dist_subst_cbd my_cbd; /* callback info for low-level callback */ 353 my_cbd.callback = callback; 354 my_cbd.cbd = cbd; 355 my_cbd.subst = 0; 356 *ep = yasm_expr__level_tree(*ep, 1, 1, 1, 0, &expr_xform_bc_dist_subst, 357 &my_cbd); 358 return my_cbd.subst; 359 } 360 361 /* Negate just a single ExprItem by building a -1*ei subexpression */ 362 static void 363 expr_xform_neg_item(yasm_expr *e, yasm_expr__item *ei) 364 { 365 yasm_expr *sube = yasm_xmalloc(sizeof(yasm_expr)); 366 367 /* Build -1*ei subexpression */ 368 sube->op = YASM_EXPR_MUL; 369 sube->line = e->line; 370 sube->numterms = 2; 371 sube->terms[0].type = YASM_EXPR_INT; 372 sube->terms[0].data.intn = yasm_intnum_create_int(-1); 373 sube->terms[1] = *ei; /* structure copy */ 374 375 /* Replace original ExprItem with subexp */ 376 ei->type = YASM_EXPR_EXPR; 377 ei->data.expn = sube; 378 } 379 380 /* Negates e by multiplying by -1, with distribution over lower-precedence 381 * operators (eg ADD) and special handling to simplify result w/ADD, NEG, and 382 * others. 383 * 384 * Returns a possibly reallocated e. 385 */ 386 static /*@only@*/ yasm_expr * 387 expr_xform_neg_helper(/*@returned@*/ /*@only@*/ yasm_expr *e) 388 { 389 yasm_expr *ne; 390 int i; 391 392 switch (e->op) { 393 case YASM_EXPR_ADD: 394 /* distribute (recursively if expr) over terms */ 395 for (i=0; i<e->numterms; i++) { 396 if (e->terms[i].type == YASM_EXPR_EXPR) 397 e->terms[i].data.expn = 398 expr_xform_neg_helper(e->terms[i].data.expn); 399 else 400 expr_xform_neg_item(e, &e->terms[i]); 401 } 402 break; 403 case YASM_EXPR_SUB: 404 /* change op to ADD, and recursively negate left side (if expr) */ 405 e->op = YASM_EXPR_ADD; 406 if (e->terms[0].type == YASM_EXPR_EXPR) 407 e->terms[0].data.expn = 408 expr_xform_neg_helper(e->terms[0].data.expn); 409 else 410 expr_xform_neg_item(e, &e->terms[0]); 411 break; 412 case YASM_EXPR_NEG: 413 /* Negating a negated value? Make it an IDENT. */ 414 e->op = YASM_EXPR_IDENT; 415 break; 416 case YASM_EXPR_IDENT: 417 /* Negating an ident? Change it into a MUL w/ -1 if there's no 418 * floatnums present below; if there ARE floatnums, recurse. 419 */ 420 if (e->terms[0].type == YASM_EXPR_FLOAT) 421 yasm_floatnum_calc(e->terms[0].data.flt, YASM_EXPR_NEG, NULL); 422 else if (e->terms[0].type == YASM_EXPR_INT) 423 yasm_intnum_calc(e->terms[0].data.intn, YASM_EXPR_NEG, NULL); 424 else if (e->terms[0].type == YASM_EXPR_EXPR && 425 yasm_expr__contains(e->terms[0].data.expn, YASM_EXPR_FLOAT)) 426 expr_xform_neg_helper(e->terms[0].data.expn); 427 else { 428 e->op = YASM_EXPR_MUL; 429 e->numterms = 2; 430 e->terms[1].type = YASM_EXPR_INT; 431 e->terms[1].data.intn = yasm_intnum_create_int(-1); 432 } 433 break; 434 default: 435 /* Everything else. MUL will be combined when it's leveled. 436 * Make a new expr (to replace e) with -1*e. 437 */ 438 ne = yasm_xmalloc(sizeof(yasm_expr)); 439 ne->op = YASM_EXPR_MUL; 440 ne->line = e->line; 441 ne->numterms = 2; 442 ne->terms[0].type = YASM_EXPR_INT; 443 ne->terms[0].data.intn = yasm_intnum_create_int(-1); 444 ne->terms[1].type = YASM_EXPR_EXPR; 445 ne->terms[1].data.expn = e; 446 return ne; 447 } 448 return e; 449 } 450 451 /* Transforms negatives into expressions that are easier to combine: 452 * -x -> -1*x 453 * a-b -> a+(-1*b) 454 * 455 * Call post-order on an expression tree to transform the entire tree. 456 * 457 * Returns a possibly reallocated e. 458 */ 459 static /*@only@*/ yasm_expr * 460 expr_xform_neg(/*@returned@*/ /*@only@*/ yasm_expr *e) 461 { 462 switch (e->op) { 463 case YASM_EXPR_NEG: 464 /* Turn -x into -1*x */ 465 e->op = YASM_EXPR_IDENT; 466 return expr_xform_neg_helper(e); 467 case YASM_EXPR_SUB: 468 /* Turn a-b into a+(-1*b) */ 469 470 /* change op to ADD, and recursively negate right side (if expr) */ 471 e->op = YASM_EXPR_ADD; 472 if (e->terms[1].type == YASM_EXPR_EXPR) 473 e->terms[1].data.expn = 474 expr_xform_neg_helper(e->terms[1].data.expn); 475 else 476 expr_xform_neg_item(e, &e->terms[1]); 477 break; 478 default: 479 break; 480 } 481 482 return e; 483 } 484 485 /* Look for simple identities that make the entire result constant: 486 * 0*&x, -1|x, etc. 487 */ 488 static int 489 expr_is_constant(yasm_expr_op op, yasm_intnum *intn) 490 { 491 int iszero = yasm_intnum_is_zero(intn); 492 return ((iszero && op == YASM_EXPR_MUL) || 493 (iszero && op == YASM_EXPR_AND) || 494 (iszero && op == YASM_EXPR_LAND) || 495 (yasm_intnum_is_neg1(intn) && op == YASM_EXPR_OR)); 496 } 497 498 /* Look for simple "left" identities like 0+x, 1*x, etc. */ 499 static int 500 expr_can_destroy_int_left(yasm_expr_op op, yasm_intnum *intn) 501 { 502 int iszero = yasm_intnum_is_zero(intn); 503 return ((yasm_intnum_is_pos1(intn) && op == YASM_EXPR_MUL) || 504 (iszero && op == YASM_EXPR_ADD) || 505 (yasm_intnum_is_neg1(intn) && op == YASM_EXPR_AND) || 506 (!iszero && op == YASM_EXPR_LAND) || 507 (iszero && op == YASM_EXPR_OR) || 508 (iszero && op == YASM_EXPR_LOR)); 509 } 510 511 /* Look for simple "right" identities like x+|-0, x*&/1 */ 512 static int 513 expr_can_destroy_int_right(yasm_expr_op op, yasm_intnum *intn) 514 { 515 int iszero = yasm_intnum_is_zero(intn); 516 int ispos1 = yasm_intnum_is_pos1(intn); 517 return ((ispos1 && op == YASM_EXPR_MUL) || 518 (ispos1 && op == YASM_EXPR_DIV) || 519 (iszero && op == YASM_EXPR_ADD) || 520 (iszero && op == YASM_EXPR_SUB) || 521 (yasm_intnum_is_neg1(intn) && op == YASM_EXPR_AND) || 522 (!iszero && op == YASM_EXPR_LAND) || 523 (iszero && op == YASM_EXPR_OR) || 524 (iszero && op == YASM_EXPR_LOR) || 525 (iszero && op == YASM_EXPR_SHL) || 526 (iszero && op == YASM_EXPR_SHR)); 527 } 528 529 /* Check for and simplify identities. Returns new number of expr terms. 530 * Sets e->op = EXPR_IDENT if numterms ends up being 1. 531 * Uses numterms parameter instead of e->numterms for basis of "new" number 532 * of terms. 533 * Assumes int_term is *only* integer term in e. 534 * NOTE: Really designed to only be used by expr_level_op(). 535 */ 536 static int 537 expr_simplify_identity(yasm_expr *e, int numterms, int *int_term, 538 int simplify_reg_mul) 539 { 540 int i; 541 int save_numterms; 542 543 /* Don't do this step if it's 1*REG. Save and restore numterms so 544 * yasm_expr__contains() works correctly. 545 */ 546 save_numterms = e->numterms; 547 e->numterms = numterms; 548 if (simplify_reg_mul || e->op != YASM_EXPR_MUL 549 || !yasm_intnum_is_pos1(e->terms[*int_term].data.intn) 550 || !yasm_expr__contains(e, YASM_EXPR_REG)) { 551 /* Check for simple identities that delete the intnum. 552 * Don't delete if the intnum is the only thing in the expn. 553 */ 554 if ((*int_term == 0 && numterms > 1 && 555 expr_can_destroy_int_left(e->op, e->terms[0].data.intn)) || 556 (*int_term > 0 && 557 expr_can_destroy_int_right(e->op, 558 e->terms[*int_term].data.intn))) { 559 /* Delete the intnum */ 560 yasm_intnum_destroy(e->terms[*int_term].data.intn); 561 562 /* Slide everything to its right over by 1 */ 563 if (*int_term != numterms-1) /* if it wasn't last.. */ 564 memmove(&e->terms[*int_term], &e->terms[*int_term+1], 565 (numterms-1-*int_term)*sizeof(yasm_expr__item)); 566 567 /* Update numterms */ 568 numterms--; 569 *int_term = -1; /* no longer an int term */ 570 } 571 } 572 e->numterms = save_numterms; 573 574 /* Check for simple identites that delete everything BUT the intnum. 575 * Don't bother if the intnum is the only thing in the expn. 576 */ 577 if (numterms > 1 && *int_term != -1 && 578 expr_is_constant(e->op, e->terms[*int_term].data.intn)) { 579 /* Loop through, deleting everything but the integer term */ 580 for (i=0; i<e->numterms; i++) 581 if (i != *int_term) 582 expr_delete_term(&e->terms[i], 1); 583 584 /* Move integer term to the first term (if not already there) */ 585 if (*int_term != 0) 586 e->terms[0] = e->terms[*int_term]; /* structure copy */ 587 588 /* Set numterms to 1 */ 589 numterms = 1; 590 } 591 592 /* Compute NOT, NEG, and LNOT on single intnum. */ 593 if (numterms == 1 && *int_term == 0 && 594 (e->op == YASM_EXPR_NOT || e->op == YASM_EXPR_NEG || 595 e->op == YASM_EXPR_LNOT)) 596 yasm_intnum_calc(e->terms[0].data.intn, e->op, NULL); 597 598 /* Change expression to IDENT if possible. */ 599 if (numterms == 1) 600 e->op = YASM_EXPR_IDENT; 601 602 /* Return the updated numterms */ 603 return numterms; 604 } 605 606 /* Levels the expression tree starting at e. Eg: 607 * a+(b+c) -> a+b+c 608 * (a+b)+(c+d) -> a+b+c+d 609 * Naturally, only levels operators that allow more than two operand terms. 610 * NOTE: only does *one* level of leveling (no recursion). Should be called 611 * post-order on a tree to combine deeper levels. 612 * Also brings up any IDENT values into the current level (for ALL operators). 613 * Folds (combines by evaluation) *integer* constant values if fold_const != 0. 614 * 615 * Returns a possibly reallocated e. 616 */ 617 /*@-mustfree@*/ 618 static /*@only@*/ yasm_expr * 619 expr_level_op(/*@returned@*/ /*@only@*/ yasm_expr *e, int fold_const, 620 int simplify_ident, int simplify_reg_mul) 621 { 622 int i, j, o, fold_numterms, level_numterms, level_fold_numterms; 623 int first_int_term = -1; 624 625 /* Determine how many operands will need to be brought up (for leveling). 626 * Go ahead and bring up any IDENT'ed values. 627 */ 628 while (e->op == YASM_EXPR_IDENT && e->terms[0].type == YASM_EXPR_EXPR) { 629 yasm_expr *sube = e->terms[0].data.expn; 630 yasm_xfree(e); 631 e = sube; 632 } 633 634 /* If non-numeric expression, don't fold constants. */ 635 if (e->op > YASM_EXPR_NONNUM) 636 fold_const = 0; 637 638 level_numterms = e->numterms; 639 level_fold_numterms = 0; 640 for (i=0; i<e->numterms; i++) { 641 /* Search downward until we find something *other* than an 642 * IDENT, then bring it up to the current level. 643 */ 644 while (e->terms[i].type == YASM_EXPR_EXPR && 645 e->terms[i].data.expn->op == YASM_EXPR_IDENT) { 646 yasm_expr *sube = e->terms[i].data.expn; 647 e->terms[i] = sube->terms[0]; 648 yasm_xfree(sube); 649 } 650 651 if (e->terms[i].type == YASM_EXPR_EXPR && 652 e->terms[i].data.expn->op == e->op) { 653 /* It's an expression w/the same operator, add in its numterms. 654 * But don't forget to subtract one for the expr itself! 655 */ 656 level_numterms += e->terms[i].data.expn->numterms - 1; 657 658 /* If we're folding constants, count up the number of constants 659 * that will be merged in. 660 */ 661 if (fold_const) 662 for (j=0; j<e->terms[i].data.expn->numterms; j++) 663 if (e->terms[i].data.expn->terms[j].type == 664 YASM_EXPR_INT) 665 level_fold_numterms++; 666 } 667 668 /* Find the first integer term (if one is present) if we're folding 669 * constants. 670 */ 671 if (fold_const && first_int_term == -1 && 672 e->terms[i].type == YASM_EXPR_INT) 673 first_int_term = i; 674 } 675 676 /* Look for other integer terms if there's one and combine. 677 * Also eliminate empty spaces when combining and adjust numterms 678 * variables. 679 */ 680 fold_numterms = e->numterms; 681 if (first_int_term != -1) { 682 for (i=first_int_term+1, o=first_int_term+1; i<e->numterms; i++) { 683 if (e->terms[i].type == YASM_EXPR_INT) { 684 yasm_intnum_calc(e->terms[first_int_term].data.intn, e->op, 685 e->terms[i].data.intn); 686 fold_numterms--; 687 level_numterms--; 688 /* make sure to delete folded intnum */ 689 yasm_intnum_destroy(e->terms[i].data.intn); 690 } else if (o != i) { 691 /* copy term if it changed places */ 692 e->terms[o++] = e->terms[i]; 693 } else 694 o++; 695 } 696 697 if (simplify_ident) { 698 int new_fold_numterms; 699 /* Simplify identities and make IDENT if possible. */ 700 new_fold_numterms = 701 expr_simplify_identity(e, fold_numterms, &first_int_term, 702 simplify_reg_mul); 703 level_numterms -= fold_numterms-new_fold_numterms; 704 fold_numterms = new_fold_numterms; 705 } 706 if (fold_numterms == 1) 707 e->op = YASM_EXPR_IDENT; 708 } 709 710 /* Only level operators that allow more than two operand terms. 711 * Also don't bother leveling if it's not necessary to bring up any terms. 712 */ 713 if ((e->op != YASM_EXPR_ADD && e->op != YASM_EXPR_MUL && 714 e->op != YASM_EXPR_OR && e->op != YASM_EXPR_AND && 715 e->op != YASM_EXPR_LOR && e->op != YASM_EXPR_LAND && 716 e->op != YASM_EXPR_LXOR && e->op != YASM_EXPR_XOR) || 717 level_numterms <= fold_numterms) { 718 /* Downsize e if necessary */ 719 if (fold_numterms < e->numterms && e->numterms > 2) 720 e = yasm_xrealloc(e, sizeof(yasm_expr)+((fold_numterms<2) ? 0 : 721 sizeof(yasm_expr__item)*(fold_numterms-2))); 722 /* Update numterms */ 723 e->numterms = fold_numterms; 724 return e; 725 } 726 727 /* Adjust numterms for constant folding from terms being "pulled up". 728 * Careful: if there's no integer term in e, then save space for it. 729 */ 730 if (fold_const) { 731 level_numterms -= level_fold_numterms; 732 if (first_int_term == -1 && level_fold_numterms != 0) 733 level_numterms++; 734 } 735 736 /* Alloc more (or conceivably less, but not usually) space for e */ 737 e = yasm_xrealloc(e, sizeof(yasm_expr)+((level_numterms<2) ? 0 : 738 sizeof(yasm_expr__item)*(level_numterms-2))); 739 740 /* Copy up ExprItem's. Iterate from right to left to keep the same 741 * ordering as was present originally. 742 * Combine integer terms as necessary. 743 */ 744 for (i=fold_numterms-1, o=level_numterms-1; i>=0; i--) { 745 if (e->terms[i].type == YASM_EXPR_EXPR && 746 e->terms[i].data.expn->op == e->op) { 747 /* bring up subexpression */ 748 yasm_expr *sube = e->terms[i].data.expn; 749 750 /* copy terms right to left */ 751 for (j=sube->numterms-1; j>=0; j--) { 752 if (fold_const && sube->terms[j].type == YASM_EXPR_INT) { 753 /* Need to fold it in.. but if there's no int term already, 754 * just copy into a new one. 755 */ 756 if (first_int_term == -1) { 757 first_int_term = o--; 758 e->terms[first_int_term] = sube->terms[j]; /* struc */ 759 } else { 760 yasm_intnum_calc(e->terms[first_int_term].data.intn, 761 e->op, sube->terms[j].data.intn); 762 /* make sure to delete folded intnum */ 763 yasm_intnum_destroy(sube->terms[j].data.intn); 764 } 765 } else { 766 if (o == first_int_term) 767 o--; 768 e->terms[o--] = sube->terms[j]; /* structure copy */ 769 } 770 } 771 772 /* delete subexpression, but *don't delete nodes* (as we've just 773 * copied them!) 774 */ 775 yasm_xfree(sube); 776 } else if (o != i) { 777 /* copy operand if it changed places */ 778 if (o == first_int_term) 779 o--; 780 e->terms[o] = e->terms[i]; 781 /* If we moved the first_int_term, change first_int_num too */ 782 if (i == first_int_term) 783 first_int_term = o; 784 o--; 785 } else 786 o--; 787 } 788 789 /* Simplify identities, make IDENT if possible, and save to e->numterms. */ 790 if (simplify_ident && first_int_term != -1) { 791 e->numterms = expr_simplify_identity(e, level_numterms, 792 &first_int_term, simplify_reg_mul); 793 } else { 794 e->numterms = level_numterms; 795 if (level_numterms == 1) 796 e->op = YASM_EXPR_IDENT; 797 } 798 799 return e; 800 } 801 /*@=mustfree@*/ 802 803 typedef SLIST_HEAD(yasm__exprhead, yasm__exprentry) yasm__exprhead; 804 typedef struct yasm__exprentry { 805 /*@reldef@*/ SLIST_ENTRY(yasm__exprentry) next; 806 /*@null@*/ const yasm_expr *e; 807 } yasm__exprentry; 808 809 static yasm_expr * 810 expr_expand_equ(yasm_expr *e, yasm__exprhead *eh) 811 { 812 int i; 813 yasm__exprentry ee; 814 815 /* traverse terms */ 816 for (i=0; i<e->numterms; i++) { 817 const yasm_expr *equ_expr; 818 819 /* Expand equ's. */ 820 if (e->terms[i].type == YASM_EXPR_SYM && 821 (equ_expr = yasm_symrec_get_equ(e->terms[i].data.sym))) { 822 yasm__exprentry *np; 823 824 /* Check for circular reference */ 825 SLIST_FOREACH(np, eh, next) { 826 if (np->e == equ_expr) { 827 yasm_error_set(YASM_ERROR_TOO_COMPLEX, 828 N_("circular reference detected")); 829 return e; 830 } 831 } 832 833 e->terms[i].type = YASM_EXPR_EXPR; 834 e->terms[i].data.expn = yasm_expr_copy(equ_expr); 835 836 /* Remember we saw this equ and recurse */ 837 ee.e = equ_expr; 838 SLIST_INSERT_HEAD(eh, &ee, next); 839 e->terms[i].data.expn = expr_expand_equ(e->terms[i].data.expn, eh); 840 SLIST_REMOVE_HEAD(eh, next); 841 } else if (e->terms[i].type == YASM_EXPR_EXPR) 842 /* Recurse */ 843 e->terms[i].data.expn = expr_expand_equ(e->terms[i].data.expn, eh); 844 } 845 846 return e; 847 } 848 849 static yasm_expr * 850 expr_level_tree(yasm_expr *e, int fold_const, int simplify_ident, 851 int simplify_reg_mul, int calc_bc_dist, 852 yasm_expr_xform_func expr_xform_extra, 853 void *expr_xform_extra_data) 854 { 855 int i; 856 857 e = expr_xform_neg(e); 858 859 /* traverse terms */ 860 for (i=0; i<e->numterms; i++) { 861 /* Recurse */ 862 if (e->terms[i].type == YASM_EXPR_EXPR) 863 e->terms[i].data.expn = 864 expr_level_tree(e->terms[i].data.expn, fold_const, 865 simplify_ident, simplify_reg_mul, calc_bc_dist, 866 expr_xform_extra, expr_xform_extra_data); 867 } 868 869 /* Check for SEG of SEG:OFF, if we match, simplify to just the segment */ 870 if (e->op == YASM_EXPR_SEG && e->terms[0].type == YASM_EXPR_EXPR && 871 e->terms[0].data.expn->op == YASM_EXPR_SEGOFF) { 872 e->op = YASM_EXPR_IDENT; 873 e->terms[0].data.expn->op = YASM_EXPR_IDENT; 874 /* Destroy the second (offset) term */ 875 e->terms[0].data.expn->numterms = 1; 876 expr_delete_term(&e->terms[0].data.expn->terms[1], 1); 877 } 878 879 /* do callback */ 880 e = expr_level_op(e, fold_const, simplify_ident, simplify_reg_mul); 881 if (calc_bc_dist || expr_xform_extra) { 882 if (calc_bc_dist) 883 e = expr_xform_bc_dist(e); 884 if (expr_xform_extra) 885 e = expr_xform_extra(e, expr_xform_extra_data); 886 e = expr_level_tree(e, fold_const, simplify_ident, simplify_reg_mul, 887 0, NULL, NULL); 888 } 889 return e; 890 } 891 892 /* Level an entire expn tree, expanding equ's as we go */ 893 yasm_expr * 894 yasm_expr__level_tree(yasm_expr *e, int fold_const, int simplify_ident, 895 int simplify_reg_mul, int calc_bc_dist, 896 yasm_expr_xform_func expr_xform_extra, 897 void *expr_xform_extra_data) 898 { 899 yasm__exprhead eh; 900 SLIST_INIT(&eh); 901 902 if (!e) 903 return 0; 904 905 e = expr_expand_equ(e, &eh); 906 e = expr_level_tree(e, fold_const, simplify_ident, simplify_reg_mul, 907 calc_bc_dist, expr_xform_extra, expr_xform_extra_data); 908 909 return e; 910 } 911 912 /* Comparison function for expr_order_terms(). 913 * Assumes ExprType enum is in canonical order. 914 */ 915 static int 916 expr_order_terms_compare(const void *va, const void *vb) 917 { 918 const yasm_expr__item *a = va, *b = vb; 919 return (a->type - b->type); 920 } 921 922 /* Reorder terms of e into canonical order. Only reorders if reordering 923 * doesn't change meaning of expression. (eg, doesn't reorder SUB). 924 * Canonical order: REG, INT, FLOAT, SYM, EXPR. 925 * Multiple terms of a single type are kept in the same order as in 926 * the original expression. 927 * NOTE: Only performs reordering on *one* level (no recursion). 928 */ 929 void 930 yasm_expr__order_terms(yasm_expr *e) 931 { 932 /* don't bother reordering if only one element */ 933 if (e->numterms == 1) 934 return; 935 936 /* only reorder some types of operations */ 937 switch (e->op) { 938 case YASM_EXPR_ADD: 939 case YASM_EXPR_MUL: 940 case YASM_EXPR_OR: 941 case YASM_EXPR_AND: 942 case YASM_EXPR_XOR: 943 case YASM_EXPR_LOR: 944 case YASM_EXPR_LAND: 945 case YASM_EXPR_LXOR: 946 /* Use mergesort to sort. It's fast on already sorted values and a 947 * stable sort (multiple terms of same type are kept in the same 948 * order). 949 */ 950 yasm__mergesort(e->terms, (size_t)e->numterms, 951 sizeof(yasm_expr__item), expr_order_terms_compare); 952 break; 953 default: 954 break; 955 } 956 } 957 958 static void 959 expr_item_copy(yasm_expr__item *dest, const yasm_expr__item *src) 960 { 961 dest->type = src->type; 962 switch (src->type) { 963 case YASM_EXPR_SYM: 964 /* Symbols don't need to be copied */ 965 dest->data.sym = src->data.sym; 966 break; 967 case YASM_EXPR_PRECBC: 968 /* Nor do direct bytecode references */ 969 dest->data.precbc = src->data.precbc; 970 break; 971 case YASM_EXPR_EXPR: 972 dest->data.expn = yasm_expr__copy_except(src->data.expn, -1); 973 break; 974 case YASM_EXPR_INT: 975 dest->data.intn = yasm_intnum_copy(src->data.intn); 976 break; 977 case YASM_EXPR_FLOAT: 978 dest->data.flt = yasm_floatnum_copy(src->data.flt); 979 break; 980 case YASM_EXPR_REG: 981 dest->data.reg = src->data.reg; 982 break; 983 case YASM_EXPR_SUBST: 984 dest->data.subst = src->data.subst; 985 break; 986 default: 987 break; 988 } 989 } 990 991 /* Copy entire expression EXCEPT for index "except" at *top level only*. */ 992 yasm_expr * 993 yasm_expr__copy_except(const yasm_expr *e, int except) 994 { 995 yasm_expr *n; 996 int i; 997 998 n = yasm_xmalloc(sizeof(yasm_expr) + 999 sizeof(yasm_expr__item)*(e->numterms<2?0:e->numterms-2)); 1000 1001 n->op = e->op; 1002 n->line = e->line; 1003 n->numterms = e->numterms; 1004 for (i=0; i<e->numterms; i++) { 1005 if (i != except) 1006 expr_item_copy(&n->terms[i], &e->terms[i]); 1007 } 1008 1009 return n; 1010 } 1011 1012 static void 1013 expr_delete_term(yasm_expr__item *term, int recurse) 1014 { 1015 switch (term->type) { 1016 case YASM_EXPR_INT: 1017 yasm_intnum_destroy(term->data.intn); 1018 break; 1019 case YASM_EXPR_FLOAT: 1020 yasm_floatnum_destroy(term->data.flt); 1021 break; 1022 case YASM_EXPR_EXPR: 1023 if (recurse) 1024 yasm_expr_destroy(term->data.expn); 1025 break; 1026 default: 1027 break; 1028 } 1029 } 1030 1031 static int 1032 expr_destroy_each(/*@only@*/ yasm_expr *e, /*@unused@*/ void *d) 1033 { 1034 int i; 1035 for (i=0; i<e->numterms; i++) 1036 expr_delete_term(&e->terms[i], 0); 1037 yasm_xfree(e); /* free ourselves */ 1038 return 0; /* don't stop recursion */ 1039 } 1040 1041 /*@-mustfree@*/ 1042 void 1043 yasm_expr_destroy(yasm_expr *e) 1044 { 1045 expr_traverse_nodes_post(e, NULL, expr_destroy_each); 1046 } 1047 /*@=mustfree@*/ 1048 1049 int 1050 yasm_expr_is_op(const yasm_expr *e, yasm_expr_op op) 1051 { 1052 return (e->op == op); 1053 } 1054 1055 static int 1056 expr_contains_callback(const yasm_expr__item *ei, void *d) 1057 { 1058 yasm_expr__type *t = d; 1059 return (ei->type & *t); 1060 } 1061 1062 int 1063 yasm_expr__contains(const yasm_expr *e, yasm_expr__type t) 1064 { 1065 return yasm_expr__traverse_leaves_in_const(e, &t, expr_contains_callback); 1066 } 1067 1068 typedef struct subst_cbd { 1069 unsigned int num_items; 1070 const yasm_expr__item *items; 1071 } subst_cbd; 1072 1073 static int 1074 expr_subst_callback(yasm_expr__item *ei, void *d) 1075 { 1076 subst_cbd *cbd = d; 1077 if (ei->type != YASM_EXPR_SUBST) 1078 return 0; 1079 if (ei->data.subst >= cbd->num_items) 1080 return 1; /* error */ 1081 expr_item_copy(ei, &cbd->items[ei->data.subst]); 1082 return 0; 1083 } 1084 1085 int 1086 yasm_expr__subst(yasm_expr *e, unsigned int num_items, 1087 const yasm_expr__item *items) 1088 { 1089 subst_cbd cbd; 1090 cbd.num_items = num_items; 1091 cbd.items = items; 1092 return yasm_expr__traverse_leaves_in(e, &cbd, expr_subst_callback); 1093 } 1094 1095 /* Traverse over expression tree, calling func for each operation AFTER the 1096 * branches (if expressions) have been traversed (eg, postorder 1097 * traversal). The data pointer d is passed to each func call. 1098 * 1099 * Stops early (and returns 1) if func returns 1. Otherwise returns 0. 1100 */ 1101 static int 1102 expr_traverse_nodes_post(yasm_expr *e, void *d, 1103 int (*func) (/*@null@*/ yasm_expr *e, 1104 /*@null@*/ void *d)) 1105 { 1106 int i; 1107 1108 if (!e) 1109 return 0; 1110 1111 /* traverse terms */ 1112 for (i=0; i<e->numterms; i++) { 1113 if (e->terms[i].type == YASM_EXPR_EXPR && 1114 expr_traverse_nodes_post(e->terms[i].data.expn, d, func)) 1115 return 1; 1116 } 1117 1118 /* do callback */ 1119 return func(e, d); 1120 } 1121 1122 /* Traverse over expression tree in order, calling func for each leaf 1123 * (non-operation). The data pointer d is passed to each func call. 1124 * 1125 * Stops early (and returns 1) if func returns 1. Otherwise returns 0. 1126 */ 1127 int 1128 yasm_expr__traverse_leaves_in_const(const yasm_expr *e, void *d, 1129 int (*func) (/*@null@*/ const yasm_expr__item *ei, /*@null@*/ void *d)) 1130 { 1131 int i; 1132 1133 if (!e) 1134 return 0; 1135 1136 for (i=0; i<e->numterms; i++) { 1137 if (e->terms[i].type == YASM_EXPR_EXPR) { 1138 if (yasm_expr__traverse_leaves_in_const(e->terms[i].data.expn, d, 1139 func)) 1140 return 1; 1141 } else { 1142 if (func(&e->terms[i], d)) 1143 return 1; 1144 } 1145 } 1146 return 0; 1147 } 1148 1149 /* Traverse over expression tree in order, calling func for each leaf 1150 * (non-operation). The data pointer d is passed to each func call. 1151 * 1152 * Stops early (and returns 1) if func returns 1. Otherwise returns 0. 1153 */ 1154 int 1155 yasm_expr__traverse_leaves_in(yasm_expr *e, void *d, 1156 int (*func) (/*@null@*/ yasm_expr__item *ei, /*@null@*/ void *d)) 1157 { 1158 int i; 1159 1160 if (!e) 1161 return 0; 1162 1163 for (i=0; i<e->numterms; i++) { 1164 if (e->terms[i].type == YASM_EXPR_EXPR) { 1165 if (yasm_expr__traverse_leaves_in(e->terms[i].data.expn, d, func)) 1166 return 1; 1167 } else { 1168 if (func(&e->terms[i], d)) 1169 return 1; 1170 } 1171 } 1172 return 0; 1173 } 1174 1175 yasm_expr * 1176 yasm_expr_extract_deep_segoff(yasm_expr **ep) 1177 { 1178 yasm_expr *retval; 1179 yasm_expr *e = *ep; 1180 int i; 1181 1182 /* Try to extract at this level */ 1183 retval = yasm_expr_extract_segoff(ep); 1184 if (retval) 1185 return retval; 1186 1187 /* Not at this level? Search any expr children. */ 1188 for (i=0; i<e->numterms; i++) { 1189 if (e->terms[i].type == YASM_EXPR_EXPR) { 1190 retval = yasm_expr_extract_deep_segoff(&e->terms[i].data.expn); 1191 if (retval) 1192 return retval; 1193 } 1194 } 1195 1196 /* Didn't find one */ 1197 return NULL; 1198 } 1199 1200 yasm_expr * 1201 yasm_expr_extract_segoff(yasm_expr **ep) 1202 { 1203 yasm_expr *retval; 1204 yasm_expr *e = *ep; 1205 1206 /* If not SEG:OFF, we can't do this transformation */ 1207 if (e->op != YASM_EXPR_SEGOFF) 1208 return NULL; 1209 1210 /* Extract the SEG portion out to its own expression */ 1211 if (e->terms[0].type == YASM_EXPR_EXPR) 1212 retval = e->terms[0].data.expn; 1213 else { 1214 /* Need to build IDENT expression to hold non-expression contents */ 1215 retval = yasm_xmalloc(sizeof(yasm_expr)); 1216 retval->op = YASM_EXPR_IDENT; 1217 retval->numterms = 1; 1218 retval->terms[0] = e->terms[0]; /* structure copy */ 1219 } 1220 1221 /* Delete the SEG: portion by changing the expression into an IDENT */ 1222 e->op = YASM_EXPR_IDENT; 1223 e->numterms = 1; 1224 e->terms[0] = e->terms[1]; /* structure copy */ 1225 1226 return retval; 1227 } 1228 1229 yasm_expr * 1230 yasm_expr_extract_wrt(yasm_expr **ep) 1231 { 1232 yasm_expr *retval; 1233 yasm_expr *e = *ep; 1234 1235 /* If not WRT, we can't do this transformation */ 1236 if (e->op != YASM_EXPR_WRT) 1237 return NULL; 1238 1239 /* Extract the right side portion out to its own expression */ 1240 if (e->terms[1].type == YASM_EXPR_EXPR) 1241 retval = e->terms[1].data.expn; 1242 else { 1243 /* Need to build IDENT expression to hold non-expression contents */ 1244 retval = yasm_xmalloc(sizeof(yasm_expr)); 1245 retval->op = YASM_EXPR_IDENT; 1246 retval->numterms = 1; 1247 retval->terms[0] = e->terms[1]; /* structure copy */ 1248 } 1249 1250 /* Delete the right side portion by changing the expr into an IDENT */ 1251 e->op = YASM_EXPR_IDENT; 1252 e->numterms = 1; 1253 1254 return retval; 1255 } 1256 1257 /*@-unqualifiedtrans -nullderef -nullstate -onlytrans@*/ 1258 yasm_intnum * 1259 yasm_expr_get_intnum(yasm_expr **ep, int calc_bc_dist) 1260 { 1261 *ep = yasm_expr_simplify(*ep, calc_bc_dist); 1262 1263 if ((*ep)->op == YASM_EXPR_IDENT && (*ep)->terms[0].type == YASM_EXPR_INT) 1264 return (*ep)->terms[0].data.intn; 1265 else 1266 return (yasm_intnum *)NULL; 1267 } 1268 /*@=unqualifiedtrans =nullderef -nullstate -onlytrans@*/ 1269 1270 /*@-unqualifiedtrans -nullderef -nullstate -onlytrans@*/ 1271 const yasm_symrec * 1272 yasm_expr_get_symrec(yasm_expr **ep, int simplify) 1273 { 1274 if (simplify) 1275 *ep = yasm_expr_simplify(*ep, 0); 1276 1277 if ((*ep)->op == YASM_EXPR_IDENT && (*ep)->terms[0].type == YASM_EXPR_SYM) 1278 return (*ep)->terms[0].data.sym; 1279 else 1280 return (yasm_symrec *)NULL; 1281 } 1282 /*@=unqualifiedtrans =nullderef -nullstate -onlytrans@*/ 1283 1284 /*@-unqualifiedtrans -nullderef -nullstate -onlytrans@*/ 1285 const uintptr_t * 1286 yasm_expr_get_reg(yasm_expr **ep, int simplify) 1287 { 1288 if (simplify) 1289 *ep = yasm_expr_simplify(*ep, 0); 1290 1291 if ((*ep)->op == YASM_EXPR_IDENT && (*ep)->terms[0].type == YASM_EXPR_REG) 1292 return &((*ep)->terms[0].data.reg); 1293 else 1294 return NULL; 1295 } 1296 /*@=unqualifiedtrans =nullderef -nullstate -onlytrans@*/ 1297 1298 void 1299 yasm_expr_print(const yasm_expr *e, FILE *f) 1300 { 1301 char opstr[8]; 1302 int i; 1303 1304 if (!e) { 1305 fprintf(f, "(nil)"); 1306 return; 1307 } 1308 1309 switch (e->op) { 1310 case YASM_EXPR_ADD: 1311 strcpy(opstr, "+"); 1312 break; 1313 case YASM_EXPR_SUB: 1314 strcpy(opstr, "-"); 1315 break; 1316 case YASM_EXPR_MUL: 1317 strcpy(opstr, "*"); 1318 break; 1319 case YASM_EXPR_DIV: 1320 strcpy(opstr, "/"); 1321 break; 1322 case YASM_EXPR_SIGNDIV: 1323 strcpy(opstr, "//"); 1324 break; 1325 case YASM_EXPR_MOD: 1326 strcpy(opstr, "%"); 1327 break; 1328 case YASM_EXPR_SIGNMOD: 1329 strcpy(opstr, "%%"); 1330 break; 1331 case YASM_EXPR_NEG: 1332 fprintf(f, "-"); 1333 opstr[0] = 0; 1334 break; 1335 case YASM_EXPR_NOT: 1336 fprintf(f, "~"); 1337 opstr[0] = 0; 1338 break; 1339 case YASM_EXPR_OR: 1340 strcpy(opstr, "|"); 1341 break; 1342 case YASM_EXPR_AND: 1343 strcpy(opstr, "&"); 1344 break; 1345 case YASM_EXPR_XOR: 1346 strcpy(opstr, "^"); 1347 break; 1348 case YASM_EXPR_XNOR: 1349 strcpy(opstr, "XNOR"); 1350 break; 1351 case YASM_EXPR_NOR: 1352 strcpy(opstr, "NOR"); 1353 break; 1354 case YASM_EXPR_SHL: 1355 strcpy(opstr, "<<"); 1356 break; 1357 case YASM_EXPR_SHR: 1358 strcpy(opstr, ">>"); 1359 break; 1360 case YASM_EXPR_LOR: 1361 strcpy(opstr, "||"); 1362 break; 1363 case YASM_EXPR_LAND: 1364 strcpy(opstr, "&&"); 1365 break; 1366 case YASM_EXPR_LNOT: 1367 strcpy(opstr, "!"); 1368 break; 1369 case YASM_EXPR_LXOR: 1370 strcpy(opstr, "^^"); 1371 break; 1372 case YASM_EXPR_LXNOR: 1373 strcpy(opstr, "LXNOR"); 1374 break; 1375 case YASM_EXPR_LNOR: 1376 strcpy(opstr, "LNOR"); 1377 break; 1378 case YASM_EXPR_LT: 1379 strcpy(opstr, "<"); 1380 break; 1381 case YASM_EXPR_GT: 1382 strcpy(opstr, ">"); 1383 break; 1384 case YASM_EXPR_LE: 1385 strcpy(opstr, "<="); 1386 break; 1387 case YASM_EXPR_GE: 1388 strcpy(opstr, ">="); 1389 break; 1390 case YASM_EXPR_NE: 1391 strcpy(opstr, "!="); 1392 break; 1393 case YASM_EXPR_EQ: 1394 strcpy(opstr, "=="); 1395 break; 1396 case YASM_EXPR_SEG: 1397 fprintf(f, "SEG "); 1398 opstr[0] = 0; 1399 break; 1400 case YASM_EXPR_WRT: 1401 strcpy(opstr, " WRT "); 1402 break; 1403 case YASM_EXPR_SEGOFF: 1404 strcpy(opstr, ":"); 1405 break; 1406 case YASM_EXPR_IDENT: 1407 opstr[0] = 0; 1408 break; 1409 default: 1410 strcpy(opstr, " !UNK! "); 1411 break; 1412 } 1413 for (i=0; i<e->numterms; i++) { 1414 switch (e->terms[i].type) { 1415 case YASM_EXPR_PRECBC: 1416 fprintf(f, "{%lx}", 1417 yasm_bc_next_offset(e->terms[i].data.precbc)); 1418 break; 1419 case YASM_EXPR_SYM: 1420 fprintf(f, "%s", yasm_symrec_get_name(e->terms[i].data.sym)); 1421 break; 1422 case YASM_EXPR_EXPR: 1423 fprintf(f, "("); 1424 yasm_expr_print(e->terms[i].data.expn, f); 1425 fprintf(f, ")"); 1426 break; 1427 case YASM_EXPR_INT: 1428 yasm_intnum_print(e->terms[i].data.intn, f); 1429 break; 1430 case YASM_EXPR_FLOAT: 1431 yasm_floatnum_print(e->terms[i].data.flt, f); 1432 break; 1433 case YASM_EXPR_REG: 1434 /* FIXME */ 1435 /*yasm_arch_reg_print(arch, e->terms[i].data.reg, f);*/ 1436 break; 1437 case YASM_EXPR_SUBST: 1438 fprintf(f, "[%u]", e->terms[i].data.subst); 1439 break; 1440 case YASM_EXPR_NONE: 1441 break; 1442 } 1443 if (i < e->numterms-1) 1444 fprintf(f, "%s", opstr); 1445 } 1446 } 1447 1448 unsigned int 1449 yasm_expr_size(const yasm_expr *e) 1450 { 1451 int i; 1452 int seen = 0; 1453 unsigned int size = 0, newsize; 1454 1455 if (e->op == YASM_EXPR_IDENT) { 1456 if (e->terms[0].type == YASM_EXPR_SYM) 1457 return yasm_symrec_get_size(e->terms[0].data.sym); 1458 return 0; 1459 } 1460 if (e->op != YASM_EXPR_ADD && e->op != YASM_EXPR_SUB) 1461 return 0; 1462 1463 for (i=0; i<e->numterms; i++) { 1464 newsize = 0; 1465 switch (e->terms[i].type) { 1466 case YASM_EXPR_EXPR: 1467 newsize = yasm_expr_size(e->terms[i].data.expn); 1468 break; 1469 case YASM_EXPR_SYM: 1470 newsize = yasm_symrec_get_size(e->terms[i].data.sym); 1471 break; 1472 default: 1473 break; 1474 } 1475 if (newsize) { 1476 size = newsize; 1477 if (seen) 1478 /* either sum of idents (?!) or substract of idents */ 1479 return 0; 1480 seen = 1; 1481 } 1482 } 1483 /* exactly one offset */ 1484 return size; 1485 } 1486 1487 const char * 1488 yasm_expr_segment(const yasm_expr *e) 1489 { 1490 int i; 1491 int seen = 0; 1492 const char *segment = NULL; 1493 1494 if (e->op == YASM_EXPR_IDENT) { 1495 if (e->terms[0].type == YASM_EXPR_SYM) 1496 return yasm_symrec_get_segment(e->terms[0].data.sym); 1497 return NULL; 1498 } 1499 if (e->op != YASM_EXPR_ADD && e->op != YASM_EXPR_SUB) 1500 return NULL; 1501 1502 for (i=0; i<e->numterms; i++) { 1503 if ((e->op == YASM_EXPR_ADD || !i) && 1504 e->terms[i].type == YASM_EXPR_EXPR) { 1505 if ((segment = yasm_expr_segment(e->terms[i].data.expn))) { 1506 if (seen) { 1507 /* either sum of idents (?!) or substract of idents */ 1508 return NULL; 1509 } 1510 seen = 1; 1511 } 1512 } 1513 } 1514 /* exactly one offset */ 1515 return segment; 1516 } 1517