]> granicus.if.org Git - yasm/commitdiff
Get rid of origin_prevbc; it's no longer needed due to yasm_value handling
authorPeter Johnson <peter@tortall.net>
Sat, 10 Jun 2006 04:01:12 +0000 (04:01 -0000)
committerPeter Johnson <peter@tortall.net>
Sat, 10 Jun 2006 04:01:12 +0000 (04:01 -0000)
of PC-relative values.

Add new yasm_value_get_intnum(); this is a simplified variant of
yasm_value_output_basic().

svn path=/branches/new-optimizer/; revision=1560

libyasm/bytecode.c
libyasm/bytecode.h
libyasm/section.c
libyasm/value.c
libyasm/value.h
modules/arch/x86/x86arch.h
modules/arch/x86/x86bc.c
modules/arch/x86/x86id.c
tools/python-yasm/bytecode.pxi
tools/python-yasm/value.pxi

index 327e8751bf8f667bb9d99f2ffe3c00a54633fad1..b49b2d98ca9a732bece0320f99cc2c7f6abcfc3d 100644 (file)
@@ -91,7 +91,7 @@ yasm_bc_create_common(const yasm_bytecode_callback *callback, void *contents,
 
     bc->line = line;
 
-    bc->offset = ~0UL;
+    bc->offset = ~0UL; /* obviously incorrect / uninitialized value */
 
     bc->opt_flags = 0;
 
index 3013eb00597ff02959949d33d913199122fc49cb..7bd740d6462c499393638f55d60f197345785e23 100644 (file)
@@ -308,17 +308,17 @@ void yasm_bc_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc);
 /*@null@*/ /*@only@*/ yasm_intnum *yasm_calc_bc_dist
     (yasm_bytecode *precbc1, yasm_bytecode *precbc2);
 
-/**
+/** Add a dependent span for a bytecode.
+ * \param add_span_data        add_span_data passed into bc_calc_len()
+ * \param bc           bytecode containing span
+ * \param id           non-zero identifier for span; may be any non-zero value
  * \param value                dependent value for bytecode expansion
- * \param origin_prevbc        origin for distance computation to relative portion of
- *                     value; value.rel and origin must be within the same
- *                     section.
  * \param neg_thres    negative threshold for long/short decision
  * \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,
-     /*@null@*/ yasm_bytecode *origin_prevbc, long neg_thres, long pos_thres);
+     long neg_thres, long pos_thres);
 
 /** Resolve EQUs in a bytecode and calculate its minimum size.
  * Generates dependent bytecode spans for cases where, if the length spanned
index 241805abecda7a6e577622396d4f62b796f92bae..4e11cf592d0881a17c7c8c0a6763d999e98024ea 100644 (file)
@@ -170,6 +170,7 @@ yasm_object_get_general(yasm_object *object, const char *name,
     STAILQ_INIT(&s->bcs);
     bc = yasm_bc_create_common(NULL, NULL, 0);
     bc->section = s;
+    bc->offset = 0;
     STAILQ_INSERT_TAIL(&s->bcs, bc, link);
 
     /* Initialize relocs */
@@ -705,7 +706,6 @@ typedef struct yasm_span {
     /*@dependent@*/ yasm_bytecode *bc;
 
     yasm_value *depval;
-    yasm_bytecode *origin_prevbc;
 
     /* Special handling: see descriptions above */
     enum {
@@ -732,15 +732,13 @@ typedef struct optimize_data {
 
 static void
 optimize_add_span(void *add_span_data, yasm_bytecode *bc, int id,
-                 yasm_value *value, /*@null@*/ yasm_bytecode *origin_prevbc,
-                 long neg_thres, long pos_thres)
+                 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;
-    span->origin_prevbc = origin_prevbc;
     span->special = NOT_SPECIAL;
     span->cur_val = 0;
     span->new_val = 0;
index 14d4d3556d38ce51b9bfcbc07adbd00418dc01b3..8e9f0a5ba7ba9542c2f08569b2b719479eceac67 100644 (file)
@@ -477,6 +477,66 @@ yasm_value_finalize(yasm_value *value)
     return yasm_value_finalize_expr(value, value->abs, valsize);
 }
 
+yasm_intnum *
+yasm_value_get_intnum(yasm_value *value, yasm_bytecode *bc)
+{
+    /*@dependent@*/ /*@null@*/ yasm_intnum *intn = NULL;
+    /*@only@*/ yasm_intnum *outval;
+    int sym_local;
+
+    if (value->abs) {
+       /* Handle integer expressions, if non-integer go ahead and return
+        * NULL.
+        */
+       intn = yasm_expr_get_intnum(&value->abs, 1);
+       if (!intn)
+           return NULL;
+    }
+
+    if (value->rel) {
+       /* If relative portion is not in bc section, return NULL.
+        * Otherwise get the relative portion's offset.
+        */
+       /*@dependent@*/ yasm_bytecode *rel_prevbc;
+       unsigned long dist;
+
+       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 */
+       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->rshift > 0) {
+           /*@only@*/ yasm_intnum *shamt =
+               yasm_intnum_create_uint((unsigned long)value->rshift);
+           yasm_intnum_calc(outval, YASM_EXPR_SHR, shamt);
+           yasm_intnum_destroy(shamt);
+       }
+       /* Add in absolute portion */
+       if (intn)
+           yasm_intnum_calc(outval, YASM_EXPR_ADD, intn);
+       return outval;
+    }
+
+    if (intn)
+       return yasm_intnum_copy(intn);
+    
+    /* No absolute or relative portions: output 0 */
+    return yasm_intnum_create_uint(0);
+}
+
 int
 yasm_value_output_basic(yasm_value *value, /*@out@*/ unsigned char *buf,
                        size_t destsize, yasm_bytecode *bc, int warn,
index 1cde996c0b60f0c3cfd31b81abb26dd8bd970221..66320554c8b9eddcb0f082cd01e3b5fb484f80b3 100644 (file)
@@ -100,6 +100,17 @@ 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.
+ * \param value                value
+ * \param bc           current bytecode (for PC-relative calculation)
+ * \note Adds in value.rel (correctly) if PC-relative and in the same section
+ *       as bc (and there is no WRT or SEG).
+ * \return Intnum if can be resolved to integer value, otherwise NULL.
+ */
+/*@null@*/ /*@only@*/ yasm_intnum *yasm_value_get_intnum
+    (yasm_value *value, yasm_bytecode *bc);
+
 /** Output value if constant or PC-relative section-local.  This should be
  * used from objfmt yasm_output_value_func() functions.
  * functions.
@@ -113,7 +124,6 @@ int yasm_value_finalize_expr(/*@out@*/ yasm_value *value,
  *                     negative for signed integer warnings,
  *                     positive for unsigned integer warnings
  * \param arch         architecture
- * \param calc_bc_dist function used to determine bytecode distance
  * \note Adds in value.rel (correctly) if PC-relative and in the same section
  *       as bc (and there is no WRT or SEG); if this is not the desired
  *       behavior, e.g. a reloc is needed in this case, don't use this
index 725d3d97eabbef6a758c122d77e2022fa87ce76d..79942e270442a676ac0c8ae8d224343c8de1e759 100644 (file)
@@ -223,7 +223,6 @@ typedef struct x86_jmp {
     x86_opcode shortop, nearop;
 
     yasm_value target;         /* jump target */
-    /*@dependent@*/ yasm_bytecode *origin_prevbc;   /* jump origin */
 
     /* which opcode are we using? */
     /* The *FORCED forms are specified in the source as such */
index 6c56ac4b8d24fc4980d17350b257f7a13057e12b..f65376f9f5cccd1996c851ea89458b399861aae3 100644 (file)
@@ -534,7 +534,7 @@ x86_bc_insn_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span,
             * critical expression.
             */
            bc->len += 1;
-           add_span(add_span_data, bc, 1, &x86_ea->ea.disp, NULL, -128, 127);
+           add_span(add_span_data, bc, 1, &x86_ea->ea.disp, -128, 127);
        } else
            bc->len + x86_ea->ea.disp.size/8;
 
@@ -583,7 +583,7 @@ x86_bc_insn_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span,
                 * expression.
                 */
                immlen = 8;
-               add_span(add_span_data, bc, 2, &imm->val, NULL, -128, 127);
+               add_span(add_span_data, bc, 2, &imm->val, -128, 127);
            }
        }
 
@@ -678,7 +678,7 @@ x86_bc_jmp_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span,
 
     if (jmp->target.rel
        && (!yasm_symrec_get_label(jmp->target.rel, &target_prevbc)
-           || target_prevbc->section != jmp->origin_prevbc->section)) {
+           || target_prevbc->section != bc->section)) {
        /* External or out of segment, so we can't check distance.
         * Allowing forced short jumps depends on the objfmt supporting
         * 8-bit relocs.  While most don't, some might, so allow it here.
@@ -695,8 +695,9 @@ x86_bc_jmp_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span,
     }
 
     /* Default to short jump and generate span */
+    jmp->op_sel = JMP_SHORT;
     bc->len += jmp->shortop.len + 1;
-    add_span(add_span_data, bc, 1, &jmp->target, jmp->origin_prevbc, -128, 127);
+    add_span(add_span_data, bc, 1, &jmp->target, -128, 127);
     return 0;
 }
 
@@ -945,6 +946,8 @@ x86_bc_jmp_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
                return 1;
            *bufp += i;
            break;
+       case JMP_NONE:
+           yasm_internal_error(N_("jump op_sel cannot be JMP_NONE in tobytes"));
        default:
            yasm_internal_error(N_("unrecognized relative jump op_sel"));
     }
index 514cc28da2c7806af0da75f7e5267b05dbe04056..326c17808ec0eff18346509a66c9903bdb854bb5 100644 (file)
@@ -2125,9 +2125,6 @@ x86_finalize_jmp(yasm_arch *arch, yasm_bytecode *bc, yasm_bytecode *prev_bc,
        yasm_error_set(YASM_ERROR_VALUE, N_("invalid jump target"));
     jmp->target.curpos_rel = 1;
 
-    /* Need to save jump origin for relative jumps. */
-    jmp->origin_prevbc = prev_bc;
-
     /* See if the user explicitly specified short/near/far. */
     switch ((int)(jinfo->operands[0] & OPTM_MASK)) {
        case OPTM_Short:
index a3f495947a2ca5af92d2a017683f10068589adf7..b5528e888f84d65377861adf45989eea6c42ad37 100644 (file)
@@ -94,8 +94,8 @@ cdef extern from "libyasm/bytecode.h":
     cdef yasm_intnum *yasm_calc_bc_dist(yasm_bytecode *precbc1,
             yasm_bytecode *precbc2)
     ctypedef void (*yasm_bc_add_span_func) (void *add_span_data,
-            yasm_bytecode *bc, int id, yasm_value *value,
-            yasm_bytecode *origin_prevbc, long neg_thres, long pos_thres)
+            yasm_bytecode *bc, int id, yasm_value *value, long neg_thres,
+            long pos_thres)
     cdef int yasm_bc_calc_len(yasm_bytecode *bc, yasm_bc_add_span_func add_span,
                               void *add_span_data)
     cdef int yasm_bc_expand(yasm_bytecode *bc, int span, long old_val,
index 11fe0d847b9efe414a3d520d55e0d55b43157631..2e89c0f7750b73ce10ee7950a5261b1c4684b428 100644 (file)
@@ -32,6 +32,8 @@ cdef extern from "libyasm/value.h":
     cdef int yasm_value_finalize(yasm_value *value)
     cdef int yasm_value_finalize_expr(yasm_value *value, yasm_expr *e,
                                       unsigned int size)
+    cdef yasm_intnum *yasm_value_get_intnum(yasm_value *value,
+                                            yasm_bytecode *bc)
     cdef int yasm_value_output_basic(yasm_value *value, unsigned char *buf,
             size_t destsize, yasm_bytecode *bc, int warn, yasm_arch *arch)
     cdef void yasm_value_print(yasm_value *value, FILE *f, int indent_level)