expr.c 47 KB

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