]> granicus.if.org Git - yasm/commitdiff
Implement first phase of align and org.
authorPeter Johnson <peter@tortall.net>
Sun, 11 Jun 2006 06:57:03 +0000 (06:57 -0000)
committerPeter Johnson <peter@tortall.net>
Sun, 11 Jun 2006 06:57:03 +0000 (06:57 -0000)
svn path=/branches/new-optimizer/; revision=1567

libyasm/bc-align.c
libyasm/bc-int.h
libyasm/bc-org.c
libyasm/bc-reserve.c
libyasm/bytecode.c
libyasm/bytecode.h
libyasm/section.c
libyasm/value.c
libyasm/value.h
tools/python-yasm/bytecode.pxi

index 152b96251a79dc807e1cd23e75e695aafd6016dc..7e74cd3fc9301fefd31080d433954b865abecef2 100644 (file)
@@ -71,7 +71,7 @@ static const yasm_bytecode_callback bc_align_callback = {
     bc_align_calc_len,
     bc_align_expand,
     bc_align_tobytes,
-    0
+    YASM_BC_SPECIAL_OFFSET
 };
 
 
@@ -121,40 +121,45 @@ static int
 bc_align_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span,
                  void *add_span_data)
 {
-    yasm_internal_error(N_("align not yet implemented"));
-#if 0
+    long neg_thres = 0;
+    long pos_thres = 0;
+
+    if (bc_align_expand(bc, 0, 0, (long)bc->offset, &neg_thres,
+                       &pos_thres) < 0)
+       return -1;
+
+    return 0;
+}
+
+static int
+bc_align_expand(yasm_bytecode *bc, int span, long old_val, long new_val,
+               /*@out@*/ long *neg_thres, /*@out@*/ long *pos_thres)
+{
     bytecode_align *align = (bytecode_align *)bc->contents;
     unsigned long end;
     unsigned long boundary =
-       yasm_intnum_get_uint(yasm_expr_get_intnum(&align->boundary, NULL));
+       yasm_intnum_get_uint(yasm_expr_get_intnum(&align->boundary, 0));
 
     if (boundary == 0) {
        bc->len = 0;
-       return YASM_BC_RESOLVE_MIN_LEN;
+       *pos_thres = 0;
+       return 0;
     }
 
-    end = bc->offset;
-    if (bc->offset & (boundary-1))
-       end = (bc->offset & ~(boundary-1)) + boundary;
+    end = new_val;
+    if (new_val & (boundary-1))
+       end = (new_val & ~(boundary-1)) + boundary;
 
-    bc->len = end - bc->offset;
+    *pos_thres = end;
+    bc->len = end - new_val;
 
     if (align->maxskip) {
        unsigned long maxskip =
-           yasm_intnum_get_uint(yasm_expr_get_intnum(&align->maxskip, NULL));
-       if ((end - bc->offset) > maxskip)
+           yasm_intnum_get_uint(yasm_expr_get_intnum(&align->maxskip, 0));
+       if ((end - new_val) > maxskip)
            bc->len = 0;
     }
-#endif
-    return 0;
-}
-
-static int
-bc_align_expand(yasm_bytecode *bc, int span, long old_val, long new_val,
-               /*@out@*/ long *neg_thres, /*@out@*/ long *pos_thres)
-{
-    yasm_internal_error(N_("align not yet implemented"));
-    return 0;
+    return 1;
 }
 
 static int
index a25eeb3bb866a8b8c5674ede015ddc3ffcfe9d01..198ca2d99a4ae6240cfbcb64bd19bd6acc486cff 100644 (file)
@@ -38,7 +38,11 @@ typedef struct yasm_bytecode_callback {
     int (*tobytes) (yasm_bytecode *bc, unsigned char **bufp, void *d,
                    yasm_output_value_func output_value,
                    /*@null@*/ yasm_output_reloc_func output_reloc);
-    int reserve;    /* Reserve space instead of outputting data */
+    enum {
+       YASM_BC_SPECIAL_NONE = 0,
+       YASM_BC_SPECIAL_RESERVE,/* Reserves space instead of outputting data */
+       YASM_BC_SPECIAL_OFFSET  /* Adjusts offset instead of calculating len */
+    } special;
 } yasm_bytecode_callback;
 
 struct yasm_bytecode {
index 277601929994aa0c2bf0590e0bfb17cc7e43fdf0..646d43cc8ec839c58fef319aa42887e28414942c 100644 (file)
@@ -64,7 +64,7 @@ static const yasm_bytecode_callback bc_org_callback = {
     bc_org_calc_len,
     bc_org_expand,
     bc_org_tobytes,
-    0
+    YASM_BC_SPECIAL_OFFSET
 };
 
 
@@ -91,20 +91,13 @@ static int
 bc_org_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span,
                void *add_span_data)
 {
-    yasm_internal_error(N_("org not yet implemented"));
-#if 0
     bytecode_org *org = (bytecode_org *)bc->contents;
+    long neg_thres = 0;
+    long pos_thres = org->start;
 
-    /* Check for overrun */
-    if (bc->offset > org->start) {
-       yasm_error_set(YASM_ERROR_GENERAL,
-                      N_("ORG overlap with already existing data"));
-       return YASM_BC_RESOLVE_ERROR | YASM_BC_RESOLVE_UNKNOWN_LEN;
-    }
+    if (bc_org_expand(bc, 0, 0, (long)bc->offset, &neg_thres, &pos_thres) < 0)
+       return -1;
 
-    /* Generate space to start offset */
-    bc->len = org->start - bc->offset;
-#endif
     return 0;
 }
 
@@ -112,8 +105,18 @@ static int
 bc_org_expand(yasm_bytecode *bc, int span, long old_val, long new_val,
              /*@out@*/ long *neg_thres, /*@out@*/ long *pos_thres)
 {
-    yasm_internal_error(N_("org not yet implemented"));
-    return 0;
+    bytecode_org *org = (bytecode_org *)bc->contents;
+
+    /* Check for overrun */
+    if ((unsigned long)new_val > org->start) {
+       yasm_error_set(YASM_ERROR_GENERAL,
+                      N_("ORG overlap with already existing data"));
+       return -1;
+    }
+
+    /* Generate space to start offset */
+    bc->len = org->start - new_val;
+    return 1;
 }
 
 static int
index 2be15122de37783e5c733c8c0d8c132eafd013c2..cc0ef845234ba61873495e5bba2f06954120c6a8 100644 (file)
@@ -63,7 +63,7 @@ static const yasm_bytecode_callback bc_reserve_callback = {
     bc_reserve_calc_len,
     yasm_bc_expand_common,
     bc_reserve_tobytes,
-    1
+    YASM_BC_SPECIAL_RESERVE
 };
 
 
index b49b2d98ca9a732bece0320f99cc2c7f6abcfc3d..1320d3e683790f411b07598cc7cb7212c8f0bf33 100644 (file)
@@ -83,20 +83,13 @@ yasm_bc_create_common(const yasm_bytecode_callback *callback, void *contents,
     yasm_bytecode *bc = yasm_xmalloc(sizeof(yasm_bytecode));
 
     bc->callback = callback;
-
     bc->section = NULL;
-
     bc->multiple = (yasm_expr *)NULL;
     bc->len = 0;
-
     bc->line = line;
-
     bc->offset = ~0UL; /* obviously incorrect / uninitialized value */
-
     bc->opt_flags = 0;
-
     bc->symrecs = NULL;
-
     bc->contents = contents;
 
     return bc;
@@ -206,29 +199,31 @@ yasm_bc_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span,
     bc->len = 0;
 
     if (!bc->callback)
-       yasm_internal_error(N_("got empty bytecode in bc_resolve"));
+       yasm_internal_error(N_("got empty bytecode in yasm_bc_calc_len"));
     else
        retval = bc->callback->calc_len(bc, add_span, add_span_data);
-#if 0
+
     /* Check for multiples */
     if (bc->multiple) {
        /*@dependent@*/ /*@null@*/ const yasm_intnum *num;
 
-       num = yasm_expr_get_intnum(&bc->multiple, NULL);
-       if (!num) {
+       num = yasm_expr_get_intnum(&bc->multiple, 0);
+       if (num)
+           bc->len *= yasm_intnum_get_uint(num);
+       else {
            if (yasm_expr__contains(bc->multiple, YASM_EXPR_FLOAT)) {
                yasm_error_set(YASM_ERROR_VALUE,
                    N_("expression must not contain floating point value"));
                retval = -1;
            } else {
                /* FIXME: Non-constant currently not allowed. */
-               yasm__error(bc->line,
-                           N_("attempt to use non-constant multiple"));
+               yasm_error_set(YASM_ERROR_VALUE,
+                              N_("attempt to use non-constant multiple"));
                retval = -1;
            }
        }
     }
-#endif
+
     /* If we got an error somewhere along the line, clear out any calc len */
     if (retval < 0)
        bc->len = 0;
@@ -241,7 +236,7 @@ yasm_bc_expand(yasm_bytecode *bc, int span, long old_val, long new_val,
               /*@out@*/ long *neg_thres, /*@out@*/ long *pos_thres)
 {
     if (!bc->callback) {
-       yasm_internal_error(N_("got empty bytecode in bc_set_long"));
+       yasm_internal_error(N_("got empty bytecode in yasm_bc_expand"));
        /*@unreached@*/
        return 0;
     } else
@@ -267,7 +262,7 @@ yasm_bc_tobytes(yasm_bytecode *bc, unsigned char *buf, unsigned long *bufsize,
     }
 
     /* special case for reserve bytecodes */
-    if (bc->callback->reserve) {
+    if (bc->callback->special == YASM_BC_SPECIAL_RESERVE) {
        *bufsize = bc->len;
        *gap = 1;
        return NULL;    /* we didn't allocate a buffer */
index 7bd740d6462c499393638f55d60f197345785e23..299bd4d69d62a127a0c488b7ff07bd648755cb28 100644 (file)
@@ -317,7 +317,7 @@ void yasm_bc_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc);
  * \param pos_thres    positive threshold for long/short decision
  */
 typedef void (*yasm_bc_add_span_func)
-    (void *add_span_data, yasm_bytecode *bc, int id, yasm_value *value,
+    (void *add_span_data, yasm_bytecode *bc, int id, const yasm_value *value,
      long neg_thres, long pos_thres);
 
 /** Resolve EQUs in a bytecode and calculate its minimum size.
index e0402c1d0d0a29e3cf28c7bcf65f3736d4771010..1f7d62e34d2d612efe2ae1686e5dc728389af3d7 100644 (file)
@@ -648,20 +648,19 @@ yasm_section_print(const yasm_section *sect, FILE *f, int indent_level,
  * Some portions are critical values that must not depend on any bytecode
  * offset (either relative or absolute).
  *
- * ALIGN: 0 length (always).  Bump offset to alignment.  Span from 0 to
- *        align bytecode, update on any change.  If span length
- *        increases past alignment, increase offset by alignment and update
- *        dependent spans.  Alignment is critical value.
- * ORG:   Same as align, but if span's length exceeds org value, error.
- *        ORG value is critical value.
+ * ALIGN/ORG/other offset-based bytecodes: Length set to bump offset to
+ *     alignment.  Span from 0 to bytecode, update on any change.  Can
+ *     update to new offset for things like align, which gets propagated
+ *     to update dependent spans.  Alignment/ORG value is critical value.
+ *     Cannot be combined with TIMES.
  *
  * How times is handled:
  *
  * TIMES: Handled separately from bytecode "raw" size.  If not span-dependent,
- *        trivial (just multiplied in at any bytecode size increase).  Span
- *        dependent times update on any change (span ID 0).  If the resultant
- *        next bytecode offset would be less than the old next bytecode offset,
- *        error.  Otherwise increase offset and update dependent spans.
+ *     trivial (just multiplied in at any bytecode size increase).  Span
+ *     dependent times update on any change (span ID 0).  If the resultant
+ *     next bytecode offset would be less than the old next bytecode offset,
+ *     error.  Otherwise increase offset and update dependent spans.
  *
  * To reduce interval tree size, a first expansion pass is performed
  * before the spans are added to the tree.
@@ -673,9 +672,8 @@ yasm_section_print(const yasm_section *sect, FILE *f, int indent_level,
  *     of all bytecodes assuming minimum length, building a list of all
  *     dependent spans as we go.
  *     "minimum" here means absolute minimum:
- *      - align 0 length, but bumps offset
+ *      - align/org (offset-based) bumps offset as normal
  *      - times values (with span-dependent values) assumed to be 0
- *      - org 0 length, but bumps offset
  *  b. Iterate over spans.  Set span length based on bytecode offsets
  *     determined in 1a.  If span is "certainly" long because the span
  *     is an absolute reference to another section (or external) or the
@@ -707,13 +705,12 @@ typedef struct yasm_span {
 
     /*@dependent@*/ yasm_bytecode *bc;
 
-    yasm_value *depval;
+    yasm_value depval;
 
     /* Special handling: see descriptions above */
     enum {
        NOT_SPECIAL = 0,
-       SPECIAL_ALIGN,
-       SPECIAL_ORG,
+       SPECIAL_BC_OFFSET,
        SPECIAL_TIMES
     } special;
 
@@ -734,13 +731,13 @@ typedef struct optimize_data {
 
 static void
 optimize_add_span(void *add_span_data, yasm_bytecode *bc, int id,
-                 yasm_value *value, long neg_thres, long pos_thres)
+                 const yasm_value *value, long neg_thres, long pos_thres)
 {
     optimize_data *optd = (optimize_data *)add_span_data;
     yasm_span *span = yasm_xmalloc(sizeof(yasm_span));
 
     span->bc = bc;
-    span->depval = value;
+    yasm_value_init_copy(&span->depval, value);
     span->special = NOT_SPECIAL;
     span->cur_val = 0;
     span->new_val = 0;
@@ -752,29 +749,42 @@ optimize_add_span(void *add_span_data, yasm_bytecode *bc, int id,
     STAILQ_INSERT_TAIL(&optd->spans, span, link);
 }
 
-static void
-update_all_bc_offsets(yasm_object *object)
+static int
+update_all_bc_offsets(yasm_object *object, yasm_errwarns *errwarns)
 {
     yasm_section *sect;
+    int saw_error = 0;
 
     STAILQ_FOREACH(sect, &object->sections, link) {
        unsigned long offset = 0;
 
-       yasm_bytecode *cur = STAILQ_FIRST(&sect->bcs);
-       yasm_bytecode *prev;
+       yasm_bytecode *bc = STAILQ_FIRST(&sect->bcs);
+       yasm_bytecode *prevbc;
 
        /* Skip our locally created empty bytecode first. */
-       prev = cur;
-       cur = STAILQ_NEXT(cur, link);
+       prevbc = bc;
+       bc = STAILQ_NEXT(bc, link);
 
        /* Iterate through the remainder, if any. */
-       while (cur) {
-           cur->offset = offset;
-           offset += cur->len;
-           prev = cur;
-           cur = STAILQ_NEXT(cur, link);
+       while (bc) {
+           if (bc->callback->special == YASM_BC_SPECIAL_OFFSET) {
+               /* Recalculate/adjust len of offset-based bytecodes here */
+               long neg_thres = 0;
+               long pos_thres = bc->offset+bc->len;
+               int retval = yasm_bc_expand(bc, 0, 0,
+                                           (long)(prevbc->offset+prevbc->len),
+                                           &neg_thres, &pos_thres);
+               yasm_errwarn_propagate(errwarns, bc->line);
+               if (retval < 0)
+                   saw_error = 1;
+           }
+           bc->offset = offset;
+           offset += bc->len;
+           prevbc = bc;
+           bc = STAILQ_NEXT(bc, link);
        }
     }
+    return saw_error;
 }
 
 void
@@ -797,31 +807,55 @@ yasm_object_optimize(yasm_object *object, yasm_arch *arch,
     STAILQ_FOREACH(sect, &object->sections, link) {
        unsigned long offset = 0;
 
-       yasm_bytecode *cur = STAILQ_FIRST(&sect->bcs);
-       yasm_bytecode *prev;
+       yasm_bytecode *bc = STAILQ_FIRST(&sect->bcs);
+       yasm_bytecode *prevbc;
 
-       cur->bc_index = bc_index++;
+       bc->bc_index = bc_index++;
 
        /* Skip our locally created empty bytecode first. */
-       prev = cur;
-       cur = STAILQ_NEXT(cur, link);
+       prevbc = bc;
+       bc = STAILQ_NEXT(bc, link);
 
        /* Iterate through the remainder, if any. */
-       while (cur) {
-           cur->bc_index = bc_index++;
+       while (bc) {
+           bc->bc_index = bc_index++;
+           bc->offset = offset;
 
-           if (yasm_bc_calc_len(cur, optimize_add_span, &optd))
+           retval = yasm_bc_calc_len(bc, optimize_add_span, &optd);
+           yasm_errwarn_propagate(errwarns, bc->line);
+           if (retval)
                saw_error = 1;
-           yasm_errwarn_propagate(errwarns, cur->line);
-
-           /* TODO: times */
-           if (cur->multiple)
-               yasm_internal_error("multiple not yet supported");
+           else {
+               if (bc->callback->special == YASM_BC_SPECIAL_OFFSET) {
+                   span = yasm_xmalloc(sizeof(yasm_span));
+
+                   span->bc = bc;
+                   yasm_value_initialize(&span->depval, NULL, 0);
+                   span->special = SPECIAL_BC_OFFSET;
+                   span->cur_val = (long)(prevbc->offset+prevbc->len);
+                   span->new_val = 0;
+                   span->neg_thres = 0;
+                   span->pos_thres = (long)(bc->offset+bc->len);
+                   span->id = 0;
+                   span->active = 1;
+
+                   STAILQ_INSERT_TAIL(&optd.spans, span, link);
+                   if (bc->multiple) {
+                       yasm_error_set(YASM_ERROR_VALUE,
+                           N_("cannot combine multiples and setting assembly position"));
+                       yasm_errwarn_propagate(errwarns, span->bc->line);
+                       saw_error = 1;
+                   }
+               }
+               /* TODO: times */
+               if (bc->len != 0 && bc->multiple) {
+                   yasm_internal_error("multiple not yet supported");
+               }
+               offset += bc->len;
+           }
 
-           cur->offset = offset;
-           offset += cur->len;
-           prev = cur;
-           cur = STAILQ_NEXT(cur, link);
+           prevbc = bc;
+           bc = STAILQ_NEXT(bc, link);
        }
     }
 
@@ -832,47 +866,61 @@ yasm_object_optimize(yasm_object *object, yasm_arch *arch,
     STAILQ_FOREACH(span, &optd.spans, link) {
        if (!span->active)
            continue;
-       yasm_value_init_copy(&val, span->depval);
-       num = yasm_value_get_intnum(&val, span->bc, 1);
-       if (num) {
-           span->new_val = yasm_intnum_get_int(num);
-           yasm_intnum_destroy(num);
-       } else {
-           /* external or too complex; force to longer form */
-           span->new_val = LONG_MAX;
-           span->active = 0;
-       }
-       yasm_value_delete(&val);
-
-       if ((span->id == 0 && span->new_val != span->cur_val) ||
-           (span->new_val < span->neg_thres
-            || span->new_val > span->pos_thres)) {
-           retval = yasm_bc_expand(span->bc, span->id, span->cur_val,
-                                   span->new_val, &neg_thres, &pos_thres);
-           yasm_errwarn_propagate(errwarns, span->bc->line);
-           if (retval < 0)
-               saw_error = 1;
-           else if (retval > 0) {
-               if (!span->active) {
-                   yasm_error_set(YASM_ERROR_VALUE,
-                                  N_("secondary expansion of an external/complex value"));
-                   yasm_errwarn_propagate(errwarns, span->bc->line);
-                   saw_error = 1;
+       switch (span->special) {
+           case NOT_SPECIAL:
+               yasm_value_init_copy(&val, &span->depval);
+               num = yasm_value_get_intnum(&val, span->bc, 1);
+               if (num) {
+                   span->new_val = yasm_intnum_get_int(num);
+                   yasm_intnum_destroy(num);
                } else {
-                   span->neg_thres = neg_thres;
-                   span->pos_thres = pos_thres;
+                   /* external or too complex; force to longest form */
+                   span->new_val = LONG_MAX;
+                   span->active = 0;
                }
-           } else
-               span->active = 0;
+               yasm_value_delete(&val);
+
+               if ((span->id == 0 && span->new_val != span->cur_val) ||
+                   (span->new_val < span->neg_thres
+                    || span->new_val > span->pos_thres)) {
+                   retval = yasm_bc_expand(span->bc, span->id, span->cur_val,
+                                           span->new_val, &neg_thres,
+                                           &pos_thres);
+                   yasm_errwarn_propagate(errwarns, span->bc->line);
+                   if (retval < 0)
+                       saw_error = 1;
+                   else if (retval > 0) {
+                       if (!span->active) {
+                           yasm_error_set(YASM_ERROR_VALUE,
+                               N_("secondary expansion of an external/complex value"));
+                           yasm_errwarn_propagate(errwarns, span->bc->line);
+                           saw_error = 1;
+                       } else {
+                           span->neg_thres = neg_thres;
+                           span->pos_thres = pos_thres;
+                       }
+                   } else
+                       span->active = 0;
+               }
+               span->cur_val = span->new_val;
+               if (span->active) {
+                   /* Add to interval tree */
+               }
+               break;
+           case SPECIAL_BC_OFFSET:
+               /* Add to interval tree; nothing else to do here */
+               break;
+           case SPECIAL_TIMES:
+               break;
        }
-       span->cur_val = span->new_val;
     }
 
     if (saw_error)
        return;
 
     /* Step 1c */
-    update_all_bc_offsets(object);
+    if (update_all_bc_offsets(object, errwarns))
+       return;
 
     /* Step 1d */
     STAILQ_FOREACH(span, &optd.spans, link) {
@@ -883,5 +931,5 @@ yasm_object_optimize(yasm_object *object, yasm_arch *arch,
     /* Step 2 */
 
     /* Step 3 */
-    update_all_bc_offsets(object);
+    update_all_bc_offsets(object, errwarns);
 }
index 94726d136ce16b87bf3f688304966ee3e87750de..067684e233c796209ce1b537a30b5a64f821fef5 100644 (file)
@@ -494,31 +494,33 @@ yasm_value_get_intnum(yasm_value *value, yasm_bytecode *bc, int calc_bc_dist)
     }
 
     if (value->rel) {
-       /* If relative portion is not in bc section, return NULL.
-        * Otherwise get the relative portion's offset.
-        */
+       /* Get the relative portion's offset. */
        /*@dependent@*/ yasm_bytecode *rel_prevbc;
        unsigned long dist;
 
-       if (!bc)
-           return NULL;    /* Can't calculate relative value */
+       if (!calc_bc_dist)
+           return NULL;    /* Don't calculate BC distance */
 
        sym_local = yasm_symrec_get_label(value->rel, &rel_prevbc);
        if (value->wrt || value->seg_of || value->section_rel || !sym_local)
            return NULL;    /* we can't handle SEG, WRT, or external symbols */
-       if (rel_prevbc->section != bc->section)
-           return NULL;    /* not in this section */
-       if (!value->curpos_rel)
-           return NULL;    /* not PC-relative */
 
-       /* Calculate value relative to current assembly position */
+       /* Calculate relative value as integer */
        dist = rel_prevbc->offset + rel_prevbc->len;
-       if (dist < bc->offset) {
-           outval = yasm_intnum_create_uint(bc->offset - dist);
-           yasm_intnum_calc(outval, YASM_EXPR_NEG, NULL);
-       } else {
-           dist -= bc->offset;
-           outval = yasm_intnum_create_uint(dist);
+       if (value->curpos_rel) {
+           /* PC-relative */
+           if (!bc)
+               return NULL;    /* Can't calculate PC-relative value */
+           if (rel_prevbc->section != bc->section)
+               return NULL;    /* not in this section */
+
+           if (dist < bc->offset) {
+               outval = yasm_intnum_create_uint(bc->offset - dist);
+               yasm_intnum_calc(outval, YASM_EXPR_NEG, NULL);
+           } else {
+               dist -= bc->offset;
+               outval = yasm_intnum_create_uint(dist);
+           }
        }
 
        if (value->rshift > 0) {
index 89a93aa8ff97d79626df26989f7b0c391111ee12..0517f189dc374e25c0ad5e676c1fd59f956a4707 100644 (file)
@@ -100,15 +100,15 @@ int yasm_value_finalize_expr(/*@out@*/ yasm_value *value,
                             /*@null@*/ /*@kept@*/ yasm_expr *e,
                             unsigned int size);
 
-/** Get value if absolute or PC-relative section-local relative.  Returns NULL
- * otherwise.
+/** Get value if absolute, pure relative, or PC-relative section-local
+ * relative.  Returns NULL otherwise.
  * \param value                value
  * \param bc           current bytecode (for PC-relative calculation); if
  *                     NULL, NULL is returned for PC-relative values.
  * \param calc_bc_dist if nonzero, calculates bytecode distances in absolute
  *                     portion of value
  * \note Adds in value.rel (correctly) if PC-relative and in the same section
- *       as bc (and there is no WRT or SEG).
+ *       as bc (and there is no WRT or SEG), or if value is pure-relative.
  * \return Intnum if can be resolved to integer value, otherwise NULL.
  */
 /*@null@*/ /*@only@*/ yasm_intnum *yasm_value_get_intnum
index b5528e888f84d65377861adf45989eea6c42ad37..6cb47042b89f4e603776956d931b3eeb5de5224d 100644 (file)
@@ -47,12 +47,6 @@ cdef extern from "libyasm/bytecode.h":
     cdef struct yasm_dataval
     cdef struct yasm_datavalhead
 
-    cdef enum yasm_bc_resolve_flags:
-        YASM_BC_RESOLVE_NONE
-        YASM_BC_RESOLVE_ERROR
-        YASM_BC_RESOLVE_MIN_LEN
-        YASM_BC_RESOLVE_UNKNOWN_LEN
-
     cdef yasm_immval* yasm_imm_create_expr(yasm_expr *e)
     cdef yasm_expr* yasm_ea_get_disp(yasm_effaddr *ea)
     cdef void yasm_ea_set_len(yasm_effaddr *ea, unsigned int len)
@@ -118,6 +112,11 @@ cdef extern from "libyasm/bytecode.h":
             int indent_level)
 
 cdef extern from "libyasm/bc-int.h":
+    cdef enum yasm_bc_special:
+        YASM_BC_SPECIAL_NONE
+        YASM_BC_SPECIAL_RESERVE
+        YASM_BC_SPECIAL_OFFSET
+
     cdef struct yasm_bytecode_callback:
         void (*destroy) (void *contents)
         void (*c_print "print") (void *contents, FILE *f, int indent_level)
@@ -129,7 +128,7 @@ cdef extern from "libyasm/bc-int.h":
         int (*tobytes) (yasm_bytecode *bc, unsigned char **bufp, void *d,
                        yasm_output_value_func output_value,
                        yasm_output_reloc_func output_reloc)
-        int reserve
+        yasm_bc_special special
 
     cdef struct yasm_bytecode:
         yasm_bytecode_callback *callback