]> granicus.if.org Git - yasm/commitdiff
* coretype.h (yasm_value): Add size field (specified in bits).
authorPeter Johnson <peter@tortall.net>
Wed, 10 May 2006 08:54:52 +0000 (08:54 -0000)
committerPeter Johnson <peter@tortall.net>
Wed, 10 May 2006 08:54:52 +0000 (08:54 -0000)
(yasm_value_output_func): Remove valsize and shift parameters.
* bytecode.h (yasm_effaddr): Remove disp_len, replacing with
need_nonzero_len.
(yasm_immval): Remove len.
* value.h (yasm_value_initialize): Add size parameter.
(yasm_value_finalize_expr): Likewise.
(yasm_value_output_basic): Remove valsize and shift parameters.

Update all implementations and users for the above.

* intnum.c (yasm_intnum_calc): Fix bug in shift right (was doing a logical
instead of arithmetic shift).

* lc3b-basic.asm, lc3b-basic.errwarn, lc3b-basic.hex: Update based on
fixed warnings.

svn path=/trunk/yasm/; revision=1534

34 files changed:
libyasm/arch.h
libyasm/bc-data.c
libyasm/bc-incbin.c
libyasm/bc-insn.c
libyasm/bc-reserve.c
libyasm/bytecode.c
libyasm/bytecode.h
libyasm/coretype.h
libyasm/intnum.c
libyasm/value.c
libyasm/value.h
modules/arch/lc3b/lc3barch.c
modules/arch/lc3b/lc3bbc.c
modules/arch/lc3b/lc3bid.re
modules/arch/lc3b/tests/lc3b-basic.asm
modules/arch/lc3b/tests/lc3b-basic.errwarn
modules/arch/lc3b/tests/lc3b-basic.hex
modules/arch/x86/x86arch.c
modules/arch/x86/x86bc.c
modules/arch/x86/x86expr.c
modules/arch/x86/x86id.c
modules/dbgfmts/codeview/cv-symline.c
modules/dbgfmts/dwarf2/dwarf2-dbgfmt.c
modules/dbgfmts/dwarf2/dwarf2-line.c
modules/listfmts/nasm/nasm-listfmt.c
modules/objfmts/bin/bin-objfmt.c
modules/objfmts/coff/coff-objfmt.c
modules/objfmts/elf/elf-objfmt.c
modules/objfmts/xdf/xdf-objfmt.c
modules/parsers/gas/gas-bison.y
modules/parsers/nasm/nasm-bison.y
modules/parsers/nasm/nasm-token.re
tools/python-yasm/coretype.pxi
tools/python-yasm/value.pxi

index 11402cbf9cf8b1e089be3c7d34643e95e140ff69..0d94c7b20ed1961aafba308c0b2925409dc5381d 100644 (file)
@@ -228,7 +228,7 @@ typedef struct yasm_arch_module {
      */
     const char *default_machine_keyword;
 
-    /** Canonical "word" size in bytes.
+    /** Canonical "word" size in bits.
      * Call yasm_arch_wordsize() to get the word size of a particular
      * #yasm_arch.
      */
@@ -469,7 +469,7 @@ int yasm_arch_intnum_tobytes(yasm_arch *arch, const yasm_intnum *intn,
                             size_t valsize, int shift,
                             const yasm_bytecode *bc, int warn);
 
-/** Get the equivalent byte size of a register.
+/** Get the equivalent size of a register in bits.
  * \param arch architecture
  * \param reg  register
  * \return 0 if there is no suitable equivalent size, otherwise the size.
index 5fe15a23883f26526a950ddd30a0cd6f6c99e454..a253534d7b1ef0a92dde5513e950648da2230499 100644 (file)
@@ -58,9 +58,6 @@ struct yasm_dataval {
 typedef struct bytecode_data {
     /* converted data (linked list) */
     yasm_datavalhead datahead;
-
-    /* final (converted) size of each value element (in bytes) */
-    unsigned int size;
 } bytecode_data;
 
 static void bc_data_destroy(void *contents);
@@ -152,7 +149,7 @@ bc_data_resolve(yasm_bytecode *bc, int save,
            case DV_EMPTY:
                break;
            case DV_VALUE:
-               bc->len += bc_data->size;
+               bc->len += dv->data.val.size/8;
                break;
            case DV_RAW:
                bc->len += dv->data.raw.len;
@@ -180,17 +177,18 @@ bc_data_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
     yasm_dataval *dv;
     unsigned char *bufp_orig = *bufp;
     yasm_intnum *intn;
+    unsigned int val_len;
 
     STAILQ_FOREACH(dv, &bc_data->datahead, link) {
        switch (dv->type) {
            case DV_EMPTY:
                break;
            case DV_VALUE:
-               if (output_value(&dv->data.val, *bufp, bc_data->size,
-                                (size_t)(bc_data->size*8), 0,
+               val_len = dv->data.val.size/8;
+               if (output_value(&dv->data.val, *bufp, val_len,
                                 (unsigned long)(*bufp-bufp_orig), bc, 1, d))
                    return 1;
-               *bufp += bc_data->size;
+               *bufp += val_len;
                break;
            case DV_RAW:
                memcpy(*bufp, dv->data.raw.contents, dv->data.raw.len);
@@ -221,7 +219,6 @@ yasm_bc_create_data(yasm_datavalhead *datahead, unsigned int size,
 
 
     yasm_dvs_initialize(&data->datahead);
-    data->size = size;
 
     /* Prescan input data for length, etc.  Careful: this needs to be
      * precisely paired with the second loop.
@@ -304,6 +301,7 @@ yasm_bc_create_data(yasm_datavalhead *datahead, unsigned int size,
                } else {
                    dvo->type = dv->type;
                    dvo->data.val = dv->data.val;   /* structure copy */
+                   dvo->data.val.size = size*8;    /* remember size */
                    dvo = STAILQ_NEXT(dvo, link);
                    len = 0;
                }
@@ -362,7 +360,7 @@ yasm_dv_create_expr(yasm_expr *e)
     yasm_dataval *retval = yasm_xmalloc(sizeof(yasm_dataval));
 
     retval->type = DV_VALUE;
-    yasm_value_initialize(&retval->data.val, e);
+    yasm_value_initialize(&retval->data.val, e, 0);
 
     return retval;
 }
index d9da18fcd6ac169a2cfc4c7ed59d0c682817120d..fd7f79e3c2c869ad815ca066934dd8ed1bbe2430 100644 (file)
@@ -105,7 +105,7 @@ bc_incbin_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc)
     bytecode_incbin *incbin = (bytecode_incbin *)bc->contents;
     yasm_value val;
 
-    if (yasm_value_finalize_expr(&val, incbin->start))
+    if (yasm_value_finalize_expr(&val, incbin->start, 0))
        yasm_error_set(YASM_ERROR_TOO_COMPLEX,
                       N_("start expression too complex"));
     else if (val.rel)
@@ -113,7 +113,7 @@ bc_incbin_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc)
                       N_("start expression not absolute"));
     incbin->start = val.abs;
 
-    if (yasm_value_finalize_expr(&val, incbin->maxlen))
+    if (yasm_value_finalize_expr(&val, incbin->maxlen, 0))
        yasm_error_set(YASM_ERROR_TOO_COMPLEX,
                       N_("maximum length expression too complex"));
     else if (val.rel)
index 531ba5da0ab3cdaed9ba3405c7382e6f69c72295..48fb2112c211d6ee230e6d84fc08105600cafaaa 100644 (file)
@@ -80,10 +80,9 @@ yasm_imm_create_expr(yasm_expr *e)
 {
     yasm_immval *im = yasm_xmalloc(sizeof(yasm_immval));
 
-    if (yasm_value_finalize_expr(&im->val, e))
+    if (yasm_value_finalize_expr(&im->val, e, 0))
        yasm_error_set(YASM_ERROR_TOO_COMPLEX,
                       N_("immediate expression too complex"));
-    im->len = 0;
     im->sign = 0;
 
     return im;
@@ -105,7 +104,7 @@ yasm_ea_set_len(yasm_effaddr *ptr, unsigned int len)
      * an explicit override, where we expect the user knows what they're doing.
      */
 
-    ptr->disp_len = (unsigned char)len;
+    ptr->disp.size = (unsigned char)len;
 }
 
 void
@@ -155,7 +154,6 @@ yasm_ea_print(const yasm_effaddr *ea, FILE *f, int indent_level)
 {
     fprintf(f, "%*sDisp:\n", indent_level, "");
     yasm_value_print(&ea->disp, f, indent_level+1);
-    fprintf(f, "%*sLen=%u\n", indent_level, "", (unsigned int)ea->disp_len);
     fprintf(f, "%*sNoSplit=%u\n", indent_level, "", (unsigned int)ea->nosplit);
     ea->callback->print(ea, f, indent_level);
 }
index 782fb0b6a604570aa4403371b5f3075a5317db31..9e1fa1a77130b5e35d8e234d5b1c93db1f7cd299 100644 (file)
@@ -90,7 +90,7 @@ bc_reserve_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc)
     bytecode_reserve *reserve = (bytecode_reserve *)bc->contents;
     yasm_value val;
 
-    if (yasm_value_finalize_expr(&val, reserve->numitems))
+    if (yasm_value_finalize_expr(&val, reserve->numitems, 0))
        yasm_error_set(YASM_ERROR_TOO_COMPLEX,
                       N_("reserve expression too complex"));
     else if (val.rel)
index 99a4c741e2826da350d694444d06e07abd6ea6ac..2ab884b005c2bc159cf3ad871946257b1a766d3a 100644 (file)
@@ -159,7 +159,7 @@ yasm_bc_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc)
     if (bc->multiple) {
        yasm_value val;
 
-       if (yasm_value_finalize_expr(&val, bc->multiple))
+       if (yasm_value_finalize_expr(&val, bc->multiple, 0))
            yasm_error_set(YASM_ERROR_TOO_COMPLEX,
                           N_("multiple expression too complex"));
        else if (val.rel)
index 1426968d86dc5e04771bcaa1cfe944b58ed02dc2..f8100da147b5c639089a75daa5d44ffb4fc8fb59 100644 (file)
@@ -60,9 +60,7 @@ struct yasm_effaddr {
 
     unsigned long segreg;      /**< segment register override (0 if none) */
 
-    unsigned char disp_len;    /**< length of disp (in bytes), 0 if unknown,
-                                *   0xff if unknown and required to be >0.
-                                */
+    unsigned char need_nonzero_len; /**< 1 if length of disp must be >0. */
     unsigned char need_disp;   /**< 1 if a displacement should be present
                                 *   in the output.
                                 */
@@ -79,7 +77,6 @@ struct yasm_effaddr {
 typedef struct yasm_immval {
     yasm_value val;            /**< the immediate value itself */
 
-    unsigned char len;         /**< final length (in bytes), 0 if unknown */
     unsigned char sign;                /**< 1 if final imm is treated as signed */
 } yasm_immval;
 
@@ -113,9 +110,9 @@ typedef enum {
 /*@observer@*/ const yasm_expr *yasm_ea_get_disp(const yasm_effaddr *ea);
 
 /** Set the length of the displacement portion of an effective address.
- * The length is specified in bytes.
+ * The length is specified in bits.
  * \param ea   effective address
- * \param len  length in bytes
+ * \param len  length in bits
  */
 void yasm_ea_set_len(yasm_effaddr *ea, unsigned int len);
 
index aa5b81191e808f0fffab6678a16f7dee661cb6d7..89e5ed355caec49a0162dce949179820447e317d 100644 (file)
@@ -152,6 +152,9 @@ typedef struct yasm_value {
      * section start.  Boolean.
      */
     unsigned int section_rel : 1;
+
+    /** Size of the value, in bits. */
+    unsigned int size : 8;
 } yasm_value;
 
 /** Maximum value of #yasm_value.rshift */
@@ -244,9 +247,6 @@ typedef /*@null@*/ /*@only@*/ yasm_intnum * (*yasm_calc_bc_dist_func)
  * \param value                value
  * \param buf          buffer for byte representation
  * \param destsize     destination size (in bytes)
- * \param valsize      size (in bits)
- * \param shift                left shift (in bits); may be negative to specify right
- *                     shift (standard warnings include truncation to boundary)
  * \param offset       offset (in bytes) of the expr contents from the start
  *                     of the bytecode (needed for relative)
  * \param bc           current bytecode (usually passed into higher-level
@@ -261,8 +261,7 @@ typedef /*@null@*/ /*@only@*/ yasm_intnum * (*yasm_calc_bc_dist_func)
  */
 typedef int (*yasm_output_value_func)
     (yasm_value *value, /*@out@*/ unsigned char *buf, size_t destsize,
-     size_t valsize, int shift, unsigned long offset, yasm_bytecode *bc,
-     int warn, /*@null@*/ void *d);
+     unsigned long offset, yasm_bytecode *bc, int warn, /*@null@*/ void *d);
 
 /** Convert a symbol reference to its byte representation.  Usually implemented
  * by object formats and debug formats to keep track of relocations generated
index 120a7a67af3fdbcb3682b1f80e7d5e9f73131b40..160d5dd4d7171f1e679ac280d0595b95aa80cb04 100644 (file)
@@ -367,6 +367,7 @@ yasm_intnum_calc(yasm_intnum *acc, yasm_expr_op op, yasm_intnum *operand)
 {
     boolean carry = 0;
     wordptr op1, op2 = NULL;
+    N_int count;
 
     /* Always do computations with in full bit vector.
      * Bit vector results must be calculated through intermediate storage.
@@ -475,7 +476,10 @@ yasm_intnum_calc(yasm_intnum *acc, yasm_expr_op op, yasm_intnum *operand)
        case YASM_EXPR_SHR:
            if (operand->type == INTNUM_UL) {
                BitVector_Copy(result, op1);
-               BitVector_Move_Right(result, (N_int)operand->val.ul);
+               carry = BitVector_msb_(op1);
+               count = (N_int)operand->val.ul;
+               while (count-- > 0)
+                   BitVector_shift_right(result, carry);
            } else      /* don't even bother, just zero result */
                BitVector_Empty(result);
            break;
index bc80c196757c659917fca64d31439f12227a7ced..5f02f5b441430dfd3aaca3669ec9110864094e83 100644 (file)
@@ -356,15 +356,15 @@ value_finalize_scan(yasm_value *value, yasm_expr *e, int ssym_not_ok)
 }
 
 int
-yasm_value_finalize_expr(yasm_value *value, yasm_expr *e)
+yasm_value_finalize_expr(yasm_value *value, yasm_expr *e, unsigned int size)
 {
     if (!e) {
-       yasm_value_initialize(value, NULL);
+       yasm_value_initialize(value, NULL, size);
        return 0;
     }
 
     yasm_value_initialize(value, yasm_expr__level_tree
-                         (e, 1, 1, 0, NULL, NULL, NULL, NULL));
+                         (e, 1, 1, 0, NULL, NULL, NULL, NULL), size);
 
     /* quit early if there was an issue in simplify() */
     if (yasm_error_occurred())
@@ -418,26 +418,30 @@ yasm_value_finalize_expr(yasm_value *value, yasm_expr *e)
     return 0;
 }
 
+int
+yasm_value_finalize(yasm_value *value)
+{
+    unsigned int valsize = value->size;
+    return yasm_value_finalize_expr(value, value->abs, valsize);
+}
+
 int
 yasm_value_output_basic(yasm_value *value, /*@out@*/ unsigned char *buf,
-                       size_t destsize, size_t valsize, int shift,
-                       yasm_bytecode *bc, int warn, yasm_arch *arch,
-                       yasm_calc_bc_dist_func calc_bc_dist)
+                       unsigned int destsize, yasm_bytecode *bc, int warn,
+                       yasm_arch *arch, yasm_calc_bc_dist_func calc_bc_dist)
 {
     /*@dependent@*/ /*@null@*/ yasm_intnum *intn = NULL;
     /*@only@*/ yasm_intnum *outval;
     int sym_local;
     int retval = 1;
+    unsigned int valsize = value->size;
 
     if (value->abs) {
        /* Handle floating point expressions */
        if (!value->rel && value->abs->op == YASM_EXPR_IDENT
            && value->abs->terms[0].type == YASM_EXPR_FLOAT) {
-           if (shift < 0)
-               yasm_internal_error(N_("attempting to negative shift a float"));
            if (yasm_arch_floatnum_tobytes(arch, value->abs->terms[0].data.flt,
-                                          buf, destsize, valsize,
-                                          (unsigned int)shift, warn))
+                                          buf, destsize, valsize, 0, warn))
                return -1;
            else
                return 1;
@@ -494,20 +498,20 @@ yasm_value_output_basic(yasm_value *value, /*@out@*/ unsigned char *buf,
        if (intn)
            yasm_intnum_calc(outval, YASM_EXPR_ADD, intn);
        /* Output! */
-       if (yasm_arch_intnum_tobytes(arch, outval, buf, destsize, valsize,
-                                    shift, bc, warn))
+       if (yasm_arch_intnum_tobytes(arch, outval, buf, destsize, valsize, 0,
+                                    bc, warn))
            retval = -1;
        yasm_intnum_destroy(outval);
     } else if (intn) {
        /* Output just absolute portion */
-       if (yasm_arch_intnum_tobytes(arch, intn, buf, destsize, valsize,
-                                    shift, bc, warn))
+       if (yasm_arch_intnum_tobytes(arch, intn, buf, destsize, valsize, 0, bc,
+                                    warn))
            retval = -1;
     } else {
        /* No absolute or relative portions: output 0 */
        outval = yasm_intnum_create_uint(0);
-       if (yasm_arch_intnum_tobytes(arch, outval, buf, destsize, valsize,
-                                    shift, bc, warn))
+       if (yasm_arch_intnum_tobytes(arch, outval, buf, destsize, valsize, 0,
+                                    bc, warn))
            retval = -1;
        yasm_intnum_destroy(outval);
     }
index 10f33b33b015ec0cf12ee66357fd0c9b825faaee..8687f9c81929d5e71568df9b963e7c0b709b0c59 100644 (file)
  * the value.
  * \param value            value to be initialized
  * \param e        expression (kept)
+ * \param size     value size (in bits)
  */
 void yasm_value_initialize(/*@out@*/ yasm_value *value,
-                          /*@null@*/ /*@kept@*/ yasm_expr *e);
+                          /*@null@*/ /*@kept@*/ yasm_expr *e,
+                          unsigned int size);
 
 /** Initialize a #yasm_value with just a symrec.  No processing is performed,
  * the symrec is simply stuck into value.rel and the other fields are
@@ -77,6 +79,7 @@ int yasm_value_finalize(yasm_value *value);
  * symrec offset within the absolute section.
  * \param value                value to store split portions into
  * \param e            expression input
+ * \param size         value size (in bits)
  * \return Nonzero if the expr could not be split into a value for some
  *         reason (e.g. the relative portion was not added, but multiplied,
  *         etc).
@@ -86,7 +89,8 @@ int yasm_value_finalize(yasm_value *value);
  *       before the parse is complete will usually result in an error return.
  */
 int yasm_value_finalize_expr(/*@out@*/ yasm_value *value,
-                            /*@null@*/ /*@kept@*/ yasm_expr *e);
+                            /*@null@*/ /*@kept@*/ yasm_expr *e,
+                            unsigned int size);
 
 /** Output value if constant or PC-relative section-local.  This should be
  * used from objfmt yasm_output_value_func() functions.
@@ -94,9 +98,6 @@ int yasm_value_finalize_expr(/*@out@*/ yasm_value *value,
  * \param value                value
  * \param buf          buffer for byte representation
  * \param destsize     destination size (in bytes)
- * \param valsize      size (in bits)
- * \param shift                left shift (in bits); may be negative to specify right
- *                     shift (standard warnings include truncation to boundary)
  * \param bc           current bytecode (usually passed into higher-level
  *                     calling function)
  * \param warn         enables standard warnings: zero for none;
@@ -114,7 +115,7 @@ int yasm_value_finalize_expr(/*@out@*/ yasm_value *value,
  */
 int yasm_value_output_basic
     (yasm_value *value, /*@out@*/ unsigned char *buf, size_t destsize,
-     size_t valsize, int shift, yasm_bytecode *bc, int warn, yasm_arch *arch,
+     yasm_bytecode *bc, int warn, yasm_arch *arch,
      yasm_calc_bc_dist_func calc_bc_dist);
 
 /** Print a value.  For debugging purposes.
@@ -126,7 +127,7 @@ void yasm_value_print(const yasm_value *value, FILE *f, int indent_level);
 
 
 #ifndef YASM_DOXYGEN
-#define yasm_value_initialize(value, e) \
+#define yasm_value_initialize(value, e, sz) \
     do { \
        (value)->abs = e; \
        (value)->rel = NULL; \
@@ -136,9 +137,10 @@ void yasm_value_print(const yasm_value *value, FILE *f, int indent_level);
        (value)->curpos_rel = 0; \
        (value)->ip_rel = 0; \
        (value)->section_rel = 0; \
+       (value)->size = sz; \
     } while(0)
 
-#define yasm_value_init_sym(value, sym) \
+#define yasm_value_init_sym(value, sym, sz) \
     do { \
        (value)->abs = NULL; \
        (value)->rel = sym; \
@@ -148,6 +150,7 @@ void yasm_value_print(const yasm_value *value, FILE *f, int indent_level);
        (value)->curpos_rel = 0; \
        (value)->ip_rel = 0; \
        (value)->section_rel = 0; \
+       (value)->size = sz; \
     } while(0)
 
 #define yasm_value_delete(value) \
@@ -156,9 +159,6 @@ void yasm_value_print(const yasm_value *value, FILE *f, int indent_level);
        (value)->abs = NULL; \
        (value)->rel = NULL; \
     } while(0)
-
-#define yasm_value_finalize(value) \
-    yasm_value_finalize_expr(value, (value)->abs)
 #endif
 
 #endif
index 9d5ef2b6a546390f87d6176b752b0ad0f4201cf8..4792b070641d55bdfdaa646d7612934fbc2e0446 100644 (file)
@@ -134,7 +134,7 @@ lc3b_get_fill(const yasm_arch *arch)
 static unsigned int
 lc3b_get_reg_size(/*@unused@*/ yasm_arch *arch, /*@unused@*/ unsigned long reg)
 {
-    return 2;
+    return 16;
 }
 
 static unsigned long
@@ -198,6 +198,6 @@ yasm_arch_module yasm_lc3b_LTX_arch = {
     lc3b_ea_create_expr,
     lc3b_machines,
     "lc3b",
-    2,
+    16,
     2
 };
index ba2517b31a3c6adf6c89a98995b45027c2611894..59e607fa85be2c77429d8a23e8b8e59b0a6a74f5 100644 (file)
@@ -193,28 +193,33 @@ lc3b_bc_insn_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
        case LC3B_IMM_NONE:
            break;
        case LC3B_IMM_4:
-           if (output_value(&insn->imm, *bufp, 2, 4, 0, 0, bc, 1, d))
+           insn->imm.size = 4;
+           if (output_value(&insn->imm, *bufp, 2, 0, bc, 1, d))
                return 1;
            break;
        case LC3B_IMM_5:
-           if (output_value(&insn->imm, *bufp, 2, 5, 0, 0, bc, 1, d))
+           insn->imm.size = 5;
+           if (output_value(&insn->imm, *bufp, 2, 0, bc, -1, d))
                return 1;
            break;
        case LC3B_IMM_6_WORD:
-           if (output_value(&insn->imm, *bufp, 2, 6, -1, 0, bc, 1, d))
+           insn->imm.size = 6;
+           if (output_value(&insn->imm, *bufp, 2, 0, bc, 1, d))
                return 1;
            break;
        case LC3B_IMM_6_BYTE:
-           if (output_value(&insn->imm, *bufp, 2, 6, 0, 0, bc, 1, d))
+           insn->imm.size = 6;
+           if (output_value(&insn->imm, *bufp, 2, 0, bc, -1, d))
                return 1;
            break;
        case LC3B_IMM_8:
-           if (output_value(&insn->imm, *bufp, 2, 8, -1, 0, bc, 1, d))
+           insn->imm.size = 8;
+           if (output_value(&insn->imm, *bufp, 2, 0, bc, 1, d))
                return 1;
            break;
        case LC3B_IMM_9_PC:
            /* Adjust relative displacement to end of bytecode */
-           delta = yasm_intnum_create_int(-(long)bc->len);
+           delta = yasm_intnum_create_int(-1);
            if (!insn->imm.abs)
                insn->imm.abs = yasm_expr_create_ident(yasm_expr_int(delta),
                                                       bc->line);
@@ -224,11 +229,13 @@ lc3b_bc_insn_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
                                     yasm_expr_expr(insn->imm.abs),
                                     yasm_expr_int(delta), bc->line);
 
-           if (output_value(&insn->imm, *bufp, 2, 9, -1, 0, bc, 1, d))
+           insn->imm.size = 9;
+           if (output_value(&insn->imm, *bufp, 2, 0, bc, -1, d))
                return 1;
            break;
        case LC3B_IMM_9:
-           if (output_value(&insn->imm, *bufp, 2, 9, -1, 0, bc, 1, d))
+           insn->imm.size = 9;
+           if (output_value(&insn->imm, *bufp, 2, 0, bc, 1, d))
                return 1;
            break;
        default:
index 584f1e8718d91ac7754ff8c937689f6629ec2fe3..0c7e82a45369e76defa7ca9ab0e3d1e321bdb72f 100644 (file)
@@ -239,7 +239,7 @@ yasm_lc3b__finalize_insn(yasm_arch *arch, yasm_bytecode *bc,
 
     /* Copy what we can from info */
     insn = yasm_xmalloc(sizeof(lc3b_insn));
-    yasm_value_initialize(&insn->imm, NULL);
+    yasm_value_initialize(&insn->imm, NULL, 0);
     insn->imm_type = LC3B_IMM_NONE;
     insn->origin_prevbc = NULL;
     insn->opcode = info->opcode;
@@ -258,6 +258,7 @@ yasm_lc3b__finalize_insn(yasm_arch *arch, yasm_bytecode *bc,
     if (operands) {
        for(i = 0, op = yasm_ops_first(operands); op && i<info->num_operands;
            op = yasm_operand_next(op), i++) {
+
            switch ((int)(info->operands[i] & OPA_MASK)) {
                case OPA_None:
                    /* Throw away the operand contents */
@@ -275,10 +276,19 @@ yasm_lc3b__finalize_insn(yasm_arch *arch, yasm_bytecode *bc,
                    insn->opcode |= ((unsigned int)(op->data.reg & 0x7)) << 6;
                    break;
                case OPA_Imm:
+                   insn->imm_type = (info->operands[i] & OPI_MASK)>>3;
                    switch (op->type) {
                        case YASM_INSN__OPERAND_IMM:
+                           if (insn->imm_type == LC3B_IMM_6_WORD
+                               || insn->imm_type == LC3B_IMM_8
+                               || insn->imm_type == LC3B_IMM_9
+                               || insn->imm_type == LC3B_IMM_9_PC)
+                               op->data.val = yasm_expr_create(YASM_EXPR_SHR,
+                                   yasm_expr_expr(op->data.val),
+                                   yasm_expr_int(yasm_intnum_create_uint(1)),
+                                   op->data.val->line);
                            if (yasm_value_finalize_expr(&insn->imm,
-                                                        op->data.val))
+                                                        op->data.val, 0))
                                yasm_error_set(YASM_ERROR_TOO_COMPLEX,
                                    N_("immediate expression too complex"));
                            break;
@@ -286,7 +296,7 @@ yasm_lc3b__finalize_insn(yasm_arch *arch, yasm_bytecode *bc,
                            if (yasm_value_finalize_expr(&insn->imm,
                                    yasm_expr_create_ident(yasm_expr_int(
                                    yasm_intnum_create_uint(op->data.reg & 0x7)),
-                                   bc->line)))
+                                   bc->line), 0))
                                yasm_internal_error(N_("reg expr too complex?"));
                            break;
                        default:
@@ -296,16 +306,14 @@ yasm_lc3b__finalize_insn(yasm_arch *arch, yasm_bytecode *bc,
                default:
                    yasm_internal_error(N_("unknown operand action"));
            }
+       }
 
-           insn->imm_type = (info->operands[i] & OPI_MASK)>>3;
-           if (insn->imm_type == LC3B_IMM_9_PC) {
-               insn->origin_prevbc = prev_bc;
-               if (insn->imm.seg_of || insn->imm.rshift
-                   || insn->imm.curpos_rel)
-                   yasm_error_set(YASM_ERROR_VALUE,
-                                  N_("invalid jump target"));
-               insn->imm.curpos_rel = 1;
-           }
+       if (insn->imm_type == LC3B_IMM_9_PC) {
+           insn->origin_prevbc = prev_bc;
+           if (insn->imm.seg_of || insn->imm.rshift > 1
+               || insn->imm.curpos_rel)
+               yasm_error_set(YASM_ERROR_VALUE, N_("invalid jump target"));
+           insn->imm.curpos_rel = 1;
        }
     }
 
index 93b6f40f5569967d533c21850458829986192f88..4cfa7754e3025d44569a92e783b4912332ef1bdf 100644 (file)
@@ -2,7 +2,7 @@ add r7, r6, r5
 add r4, r3, 22
 label:
 and r2, r1, r0
-and r2, r5, 22
+and r2, r5, 5
 brz label
 br label2
 
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..8a232a029a3b00889e91e7138aaee721b7bbccac 100644 (file)
@@ -0,0 +1 @@
+-:2: warning: value does not fit in signed 5 bit field
index d23ea431f44000da4f0dd0d2c023541da138488b..9e90c961f34fa3e2fb81577d8ebb851292e188b8 100644 (file)
@@ -4,7 +4,7 @@ f6
 18 
 40 
 54 
-76 
+65 
 55 
 fd 
 05 
index 6103fe3781b4f2e92683f53abbbdeacebd1dabf6..52e486c17a5b2546dae2940de7bfc2a04231e6bd 100644 (file)
@@ -318,21 +318,21 @@ yasm_x86__get_reg_size(yasm_arch *arch, unsigned long reg)
     switch ((x86_expritem_reg_size)(reg & ~0xFUL)) {
        case X86_REG8:
        case X86_REG8X:
-           return 1;
+           return 8;
        case X86_REG16:
-           return 2;
+           return 16;
        case X86_REG32:
        case X86_CRREG:
        case X86_DRREG:
        case X86_TRREG:
-           return 4;
+           return 32;
        case X86_REG64:
        case X86_MMXREG:
-           return 8;
+           return 64;
        case X86_XMMREG:
-           return 16;
+           return 128;
        case X86_FPUREG:
-           return 10;
+           return 80;
        default:
            yasm_error_set(YASM_ERROR_VALUE, N_("unknown register size"));
     }
@@ -461,6 +461,6 @@ yasm_arch_module yasm_x86_LTX_arch = {
     yasm_x86__ea_create_expr,
     x86_machines,
     "x86",
-    2,
+    16,
     1
 };
index 4e2068d65d5f7b3923ece689dc6e698ab788df83..62ef563b7118a304af16ba5ac3800e18bca0181c 100644 (file)
@@ -180,8 +180,8 @@ yasm_x86__ea_create_reg(unsigned long reg, unsigned char *rex,
     x86_ea = yasm_xmalloc(sizeof(x86_effaddr));
 
     x86_ea->ea.callback = &x86_ea_callback;
-    yasm_value_initialize(&x86_ea->ea.disp, NULL);
-    x86_ea->ea.disp_len = 0;
+    yasm_value_initialize(&x86_ea->ea.disp, NULL, 0);
+    x86_ea->ea.need_nonzero_len = 0;
     x86_ea->ea.need_disp = 0;
     x86_ea->ea.nosplit = 0;
     x86_ea->ea.strong = 0;
@@ -220,8 +220,8 @@ yasm_x86__ea_create_expr(yasm_arch *arch, yasm_expr *e)
                                 yasm_expr_reg(X86_RIP), e->line);
        }
     }
-    yasm_value_initialize(&x86_ea->ea.disp, e);
-    x86_ea->ea.disp_len = 0;
+    yasm_value_initialize(&x86_ea->ea.disp, e, 0);
+    x86_ea->ea.need_nonzero_len = 0;
     x86_ea->ea.need_disp = 1;
     x86_ea->ea.nosplit = 0;
     x86_ea->ea.strong = 0;
@@ -248,8 +248,7 @@ yasm_x86__ea_create_imm(yasm_expr *imm, unsigned int im_len)
     x86_ea = yasm_xmalloc(sizeof(x86_effaddr));
 
     x86_ea->ea.callback = &x86_ea_callback;
-    yasm_value_initialize(&x86_ea->ea.disp, imm);
-    x86_ea->ea.disp_len = (unsigned char)im_len;
+    yasm_value_initialize(&x86_ea->ea.disp, imm, im_len);
     x86_ea->ea.need_disp = 1;
     x86_ea->ea.nosplit = 0;
     x86_ea->ea.strong = 0;
@@ -409,8 +408,7 @@ x86_bc_insn_print(const void *contents, FILE *f, int indent_level)
        indent_level++;
        fprintf(f, "\n");
        yasm_value_print(&insn->imm->val, f, indent_level);
-       fprintf(f, "%*sLen=%u, Sign=%u\n", indent_level, "",
-               (unsigned int)insn->imm->len,
+       fprintf(f, "%*sSign=%u\n", indent_level, "",
                (unsigned int)insn->imm->sign);
        indent_level--;
     }
@@ -551,13 +549,13 @@ x86_bc_insn_resolve(yasm_bytecode *bc, int save,
                break;
        }
 
-       if (eat.ea.disp_len != 1) {
+       if (eat.ea.disp.size != 8) {
            /* Fits into a word/dword, or unknown. */
            retval = YASM_BC_RESOLVE_NONE;  /* may not be smallest size */
 
            /* Handle unknown case, make displen word-sized */
-           if (eat.ea.disp_len == 0xff)
-               eat.ea.disp_len = (insn->common.addrsize == 16) ? 2U : 4U;
+           if (eat.ea.need_nonzero_len)
+               eat.ea.disp.size = (insn->common.addrsize == 16) ? 16 : 32;
        }
 
        /* Handle address16 postop case */
@@ -565,27 +563,28 @@ x86_bc_insn_resolve(yasm_bytecode *bc, int save,
            insn->common.addrsize = 0;
 
        /* If we had forced ea->len but had to override, save it now */
-       if (x86_ea->ea.disp_len != 0 && x86_ea->ea.disp_len != eat.ea.disp_len)
-           x86_ea->ea.disp_len = eat.ea.disp_len;
+       if (x86_ea->ea.disp.size != 0 &&
+           x86_ea->ea.disp.size != eat.ea.disp.size)
+           x86_ea->ea.disp.size = eat.ea.disp.size;
 
        if (save) {
            eat.ea.disp.abs = x86_ea->ea.disp.abs; /* Copy back original */
            *x86_ea = eat;      /* structure copy */
-           if (x86_ea->ea.disp_len == 0) {
+           if (x86_ea->ea.disp.size == 0) {
                yasm_value_delete(&x86_ea->ea.disp);
                x86_ea->ea.need_disp = 0;
            }
        }
 
        /* Compute length of ea and add to total */
-       bc->len += eat.need_modrm + (eat.need_sib ? 1:0) + eat.ea.disp_len;
+       bc->len += eat.need_modrm + (eat.need_sib ? 1:0) + eat.ea.disp.size/8;
        bc->len += (eat.ea.segreg != 0) ? 1 : 0;
     }
 
     if (imm) {
        /*@null@*/ yasm_expr *temp = NULL;
        const yasm_intnum *num = NULL;
-       unsigned int immlen = imm->len;
+       unsigned int immlen = imm->val.size;
        long val;
 
        if (imm->val.abs) {
@@ -609,11 +608,11 @@ x86_bc_insn_resolve(yasm_bytecode *bc, int save,
                    /* We can use the sign-extended byte form: shorten
                     * the immediate length to 1.
                     */
-                   immlen = 1;
+                   immlen = 8;
                    if (save) {
                        /* Make the byte form permanent. */
                        insn->opcode.opcode[0] = insn->opcode.opcode[1];
-                       imm->len = 1;
+                       imm->val.size = 8;
                        if (insn->opcode.opcode[2] != 0) {
                            insn->opcode.opcode[1] = insn->opcode.opcode[2];
                            insn->opcode.len++;
@@ -630,7 +629,7 @@ x86_bc_insn_resolve(yasm_bytecode *bc, int save,
                /* Handle signext_imm32 postop special-casing */
                if (!num || yasm_intnum_check_size(num, 32, 0, 1)) {
                    bc->len++;  /* Due to ModRM byte */
-                   immlen = 4;
+                   immlen = 32;
                    if (save) {
                        /* Throwaway REX byte */
                        unsigned char rex_temp = 0;
@@ -644,7 +643,7 @@ x86_bc_insn_resolve(yasm_bytecode *bc, int save,
 
                        /* Make the imm32s form permanent. */
                        insn->opcode.opcode[0] = insn->opcode.opcode[1];
-                       imm->len = 4;
+                       imm->val.size = 32;
                    }
                }
                /* Not really necessary, but saves confusion over it. */
@@ -680,7 +679,7 @@ x86_bc_insn_resolve(yasm_bytecode *bc, int save,
 
        yasm_expr_destroy(temp);
 
-       bc->len += immlen;
+       bc->len += immlen/8;
     }
 
     bc->len += insn->opcode.len;
@@ -945,6 +944,7 @@ x86_bc_insn_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
        if (x86_ea->ea.need_disp) {
            x86_effaddr eat = *x86_ea;  /* structure copy */
            unsigned char addrsize = insn->common.addrsize;
+           unsigned int disp_len = x86_ea->ea.disp.size/8;
 
            eat.valid_modrm = 0;    /* force checkea to actually run */
 
@@ -974,21 +974,21 @@ x86_bc_insn_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
                                         yasm_expr_expr(x86_ea->ea.disp.abs),
                                         yasm_expr_int(delta), bc->line);
            }
-           if (output_value(&x86_ea->ea.disp, *bufp, x86_ea->ea.disp_len,
-                            (size_t)(x86_ea->ea.disp_len*8), 0,
+           if (output_value(&x86_ea->ea.disp, *bufp, disp_len,
                             (unsigned long)(*bufp-bufp_orig), bc, 1, d))
                return 1;
-           *bufp += x86_ea->ea.disp_len;
+           *bufp += disp_len;
        }
     }
 
     /* Immediate (if required) */
     if (imm) {
-       if (output_value(&imm->val, *bufp, imm->len, (size_t)(imm->len*8), 0,
+       unsigned int imm_len = imm->val.size/8;
+       if (output_value(&imm->val, *bufp, imm_len,
                         (unsigned long)(*bufp-bufp_orig), bc, imm->sign?-1:1,
                         d))
            return 1;
-       *bufp += imm->len;
+       *bufp += imm_len;
     }
 
     return 0;
@@ -1034,7 +1034,8 @@ x86_bc_jmp_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
                                     yasm_expr_expr(jmp->target.abs),
                                     yasm_expr_int(delta), bc->line);
 
-           if (output_value(&jmp->target, *bufp, 1, 8, 0,
+           jmp->target.size = 8;
+           if (output_value(&jmp->target, *bufp, 1,
                             (unsigned long)(*bufp-bufp_orig), bc, -1, d))
                return 1;
            *bufp += 1;
@@ -1064,7 +1065,8 @@ x86_bc_jmp_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
                                     yasm_expr_expr(jmp->target.abs),
                                     yasm_expr_int(delta), bc->line);
 
-           if (output_value(&jmp->target, *bufp, i, i*8, 0,
+           jmp->target.size = i*8;
+           if (output_value(&jmp->target, *bufp, i,
                             (unsigned long)(*bufp-bufp_orig), bc, -1, d))
                return 1;
            *bufp += i;
@@ -1094,11 +1096,13 @@ x86_bc_jmpfar_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
 
     /* Absolute displacement: segment and offset */
     i = (opersize == 16) ? 2 : 4;
-    if (output_value(&jmpfar->offset, *bufp, i, i*8, 0,
+    jmpfar->offset.size = i*8;
+    if (output_value(&jmpfar->offset, *bufp, i,
                     (unsigned long)(*bufp-bufp_orig), bc, 1, d))
        return 1;
     *bufp += i;
-    if (output_value(&jmpfar->segment, *bufp, 2, 2*8, 0,
+    jmpfar->segment.size = 16;
+    if (output_value(&jmpfar->segment, *bufp, 2,
                     (unsigned long)(*bufp-bufp_orig), bc, 1, d))
        return 1;
     *bufp += 2;
index 50185145565ca734a51e26e0b2e312aac9d43f54..b83d79794056d64461064e74a5950a53b8d5572a 100644 (file)
@@ -401,7 +401,7 @@ x86_expr_checkea_getregusage(yasm_expr **ep, /*@null@*/ int *indexreg,
 /* Calculate the displacement length, if possible.
  * Takes several extra inputs so it can be used by both 32-bit and 16-bit
  * expressions:
- *  wordsize=2 for 16-bit, =4 for 32-bit.
+ *  wordsize=16 for 16-bit, =32 for 32-bit.
  *  noreg=1 if the *ModRM byte* has no registers used.
  *  dispreq=1 if a displacement value is *required* (even if =0).
  * Returns 0 if successfully calculated, 1 if not.
@@ -416,35 +416,35 @@ x86_checkea_calc_displen(x86_effaddr *x86_ea, unsigned int wordsize, int noreg,
 
     x86_ea->valid_modrm = 0;   /* default to not yet valid */
 
-    switch (x86_ea->ea.disp_len) {
+    switch (x86_ea->ea.disp.size) {
        case 0:
            break;
        /* If not 0, the displacement length was forced; set the Mod bits
         * appropriately and we're done with the ModRM byte.
         */
-       case 1:
+       case 8:
            /* Byte is not valid override in noreg case; fix it. */
            if (noreg) {
-               x86_ea->ea.disp_len = 0;
+               x86_ea->ea.disp.size = 0;
                yasm_warn_set(YASM_WARN_GENERAL,
                              N_("invalid displacement size; fixed"));
            } else
                x86_ea->modrm |= 0100;
            x86_ea->valid_modrm = 1;
            break;
-       case 2:
-       case 4:
-           if (wordsize != x86_ea->ea.disp_len) {
+       case 16:
+       case 32:
+           if (wordsize != x86_ea->ea.disp.size) {
                yasm_error_set(YASM_ERROR_VALUE,
                    N_("invalid effective address (displacement size)"));
                return 1;
            }
            /* 2/4 is not valid override in noreg case; fix it. */
            if (noreg) {
-               if (wordsize != x86_ea->ea.disp_len)
+               if (wordsize != x86_ea->ea.disp.size)
                    yasm_warn_set(YASM_WARN_GENERAL,
                                  N_("invalid displacement size; fixed"));
-               x86_ea->ea.disp_len = 0;
+               x86_ea->ea.disp.size = 0;
            } else
                x86_ea->modrm |= 0200;
            x86_ea->valid_modrm = 1;
@@ -454,7 +454,7 @@ x86_checkea_calc_displen(x86_effaddr *x86_ea, unsigned int wordsize, int noreg,
            yasm_internal_error(N_("strange EA displacement size"));
     }
 
-    if (x86_ea->ea.disp_len == 0) {
+    if (x86_ea->ea.disp.size == 0) {
        /* the displacement length hasn't been forced (or the forcing wasn't
         * valid), try to determine what it is.
         */
@@ -463,16 +463,14 @@ x86_checkea_calc_displen(x86_effaddr *x86_ea, unsigned int wordsize, int noreg,
             * and as the Mod bits are set to 0 by the caller, we're done
             * with the ModRM byte.
             */
-           x86_ea->ea.disp_len = wordsize;
+           x86_ea->ea.disp.size = wordsize;
            x86_ea->valid_modrm = 1;
            return 0;
        } else if (dispreq) {
            /* for BP/EBP, there *must* be a displacement value, but we
             * may not know the size (8 or 16/32) for sure right now.
-            * We can't leave displen at 0, because that just means
-            * unknown displacement, including none.
             */
-           x86_ea->ea.disp_len = 0xff;
+           x86_ea->ea.need_nonzero_len = 1;
        }
 
        if (x86_ea->ea.disp.rel ||
@@ -481,7 +479,7 @@ x86_checkea_calc_displen(x86_effaddr *x86_ea, unsigned int wordsize, int noreg,
            /* expr still has unknown values or is relative:
             * assume 16/32-bit disp
             */
-           x86_ea->ea.disp_len = wordsize;
+           x86_ea->ea.disp.size = wordsize;
            x86_ea->modrm |= 0200;
            x86_ea->valid_modrm = 1;
            return 0;
@@ -490,8 +488,8 @@ x86_checkea_calc_displen(x86_effaddr *x86_ea, unsigned int wordsize, int noreg,
        /* don't try to find out what size displacement we have if
         * displen is known.
         */
-       if (x86_ea->ea.disp_len != 0 && x86_ea->ea.disp_len != 0xff) {
-           if (x86_ea->ea.disp_len == 1)
+       if (x86_ea->ea.disp.size != 0) {
+           if (x86_ea->ea.disp.size == 8)
                x86_ea->modrm |= 0100;
            else
                x86_ea->modrm |= 0200;
@@ -505,7 +503,7 @@ x86_checkea_calc_displen(x86_effaddr *x86_ea, unsigned int wordsize, int noreg,
            dispval = 0;
 
        /* Figure out what size displacement we will have. */
-       if (x86_ea->ea.disp_len != 0xff && dispval == 0) {
+       if (!x86_ea->ea.need_nonzero_len && dispval == 0) {
            /* if we know that the displacement is 0 right now,
             * go ahead and delete the expr and make it so no
             * displacement value is included in the output.
@@ -520,11 +518,11 @@ x86_checkea_calc_displen(x86_effaddr *x86_ea, unsigned int wordsize, int noreg,
            x86_ea->ea.need_disp = 0;
        } else if (dispval >= -128 && dispval <= 127) {
            /* It fits into a signed byte */
-           x86_ea->ea.disp_len = 1;
+           x86_ea->ea.disp.size = 8;
            x86_ea->modrm |= 0100;
        } else {
            /* It's a 16/32-bit displacement */
-           x86_ea->ea.disp_len = wordsize;
+           x86_ea->ea.disp.size = wordsize;
            x86_ea->modrm |= 0200;
        }
        x86_ea->valid_modrm = 1;        /* We're done with ModRM */
@@ -572,12 +570,12 @@ yasm_x86__expr_checkea(x86_effaddr *x86_ea, unsigned char *addrsize,
         * - what registers are used in the expression
         * - the bits setting
         */
-       switch (x86_ea->ea.disp_len) {
-           case 2:
+       switch (x86_ea->ea.disp.size) {
+           case 16:
                /* must be 16-bit */
                *addrsize = 16;
                break;
-           case 8:
+           case 64:
                /* We have to support this for the MemOffs case, but it's
                 * otherwise illegal.  It's also illegal in non-64-bit mode.
                 */
@@ -588,7 +586,7 @@ yasm_x86__expr_checkea(x86_effaddr *x86_ea, unsigned char *addrsize,
                }
                *addrsize = 64;
                break;
-           case 4:
+           case 32:
                /* Must be 32-bit in 16-bit or 32-bit modes.  In 64-bit mode,
                 * we don't know unless we look at the registers, except in the
                 * MemOffs case (see the end of this function).
@@ -797,7 +795,7 @@ yasm_x86__expr_checkea(x86_effaddr *x86_ea, unsigned char *addrsize,
            x86_ea->need_sib = 0;
            /* RIP always requires a 32-bit displacement */
            x86_ea->valid_modrm = 1;
-           x86_ea->ea.disp_len = 4;
+           x86_ea->ea.disp.size = 32;
            return 0;
        } else if (indexreg == REG3264_NONE) {
            /* basereg only */
@@ -877,7 +875,7 @@ yasm_x86__expr_checkea(x86_effaddr *x86_ea, unsigned char *addrsize,
 
        /* Calculate displacement length (if possible) */
        retval = x86_checkea_calc_displen
-           (x86_ea, 4, basereg == REG3264_NONE,
+           (x86_ea, 32, basereg == REG3264_NONE,
             basereg == REG3264_EBP || basereg == REG64_R13);
        return retval;
     } else if (*addrsize == 16 && x86_ea->need_modrm && !x86_ea->valid_modrm) {
@@ -962,7 +960,7 @@ yasm_x86__expr_checkea(x86_effaddr *x86_ea, unsigned char *addrsize,
 
        /* Calculate displacement length (if possible) */
        retval = x86_checkea_calc_displen
-           (x86_ea, 2, havereg == HAVE_NONE, havereg == HAVE_BP);
+           (x86_ea, 16, havereg == HAVE_NONE, havereg == HAVE_BP);
        return retval;
     } else if (!x86_ea->need_modrm && !x86_ea->need_sib) {
        /* Special case for MOV MemOffs opcode: displacement but no modrm. */
@@ -973,10 +971,10 @@ yasm_x86__expr_checkea(x86_effaddr *x86_ea, unsigned char *addrsize,
                        N_("invalid effective address (64-bit in non-64-bit mode)"));
                    return 1;
                }
-               x86_ea->ea.disp_len = 8;
+               x86_ea->ea.disp.size = 64;
                break;
            case 32:
-               x86_ea->ea.disp_len = 4;
+               x86_ea->ea.disp.size = 32;
                break;
            case 16:
                /* 64-bit mode does not allow 16-bit addresses */
@@ -985,7 +983,7 @@ yasm_x86__expr_checkea(x86_effaddr *x86_ea, unsigned char *addrsize,
                        N_("16-bit addresses not supported in 64-bit mode"));
                    return 1;
                }
-               x86_ea->ea.disp_len = 2;
+               x86_ea->ea.disp.size = 16;
                break;
        }
     }
index 47cdb4ef803b3683eb6f594b350372fdfe84ad3b..9dd2ac880a581f5f04a1e8393eb93592b6cf7f41 100644 (file)
@@ -2062,8 +2062,8 @@ x86_finalize_jmpfar(yasm_arch *arch, yasm_bytecode *bc,
        case X86_FAR:
            /* "FAR imm" target needs to become "seg imm:imm". */
            if (yasm_value_finalize_expr(&jmpfar->offset,
-                                        yasm_expr_copy(op->data.val))
-               || yasm_value_finalize_expr(&jmpfar->segment, op->data.val))
+                                        yasm_expr_copy(op->data.val), 0)
+               || yasm_value_finalize_expr(&jmpfar->segment, op->data.val, 16))
                yasm_error_set(YASM_ERROR_TOO_COMPLEX,
                               N_("jump target expression too complex"));
            jmpfar->segment.seg_of = 1;
@@ -2073,10 +2073,10 @@ x86_finalize_jmpfar(yasm_arch *arch, yasm_bytecode *bc,
            segment = yasm_expr_extract_segoff(&op->data.val);
            if (!segment)
                yasm_internal_error(N_("didn't get SEG:OFF expression in jmpfar"));
-           if (yasm_value_finalize_expr(&jmpfar->segment, segment))
+           if (yasm_value_finalize_expr(&jmpfar->segment, segment, 16))
                yasm_error_set(YASM_ERROR_TOO_COMPLEX,
                               N_("jump target segment too complex"));
-           if (yasm_value_finalize_expr(&jmpfar->offset, op->data.val))
+           if (yasm_value_finalize_expr(&jmpfar->offset, op->data.val, 0))
                yasm_error_set(YASM_ERROR_TOO_COMPLEX,
                               N_("jump target offset too complex"));
            break;
@@ -2114,7 +2114,7 @@ x86_finalize_jmp(yasm_arch *arch, yasm_bytecode *bc, yasm_bytecode *prev_bc,
 
     jmp = yasm_xmalloc(sizeof(x86_jmp));
     x86_finalize_common(&jmp->common, jinfo, mode_bits);
-    if (yasm_value_finalize_expr(&jmp->target, op->data.val))
+    if (yasm_value_finalize_expr(&jmp->target, op->data.val, 0))
        yasm_error_set(YASM_ERROR_TOO_COMPLEX,
                       N_("jump target expression too complex"));
     if (jmp->target.seg_of || jmp->target.rshift || jmp->target.curpos_rel)
@@ -2230,9 +2230,9 @@ yasm_x86__finalize_insn(yasm_arch *arch, yasm_bytecode *bc,
     unsigned char im_sign;
     unsigned char spare;
     int i;
-    unsigned int size_lookup[] = {0, 1, 2, 4, 8, 10, 16, 0};
+    unsigned int size_lookup[] = {0, 8, 16, 32, 64, 80, 128, 0};
 
-    size_lookup[7] = mode_bits>>3;
+    size_lookup[7] = mode_bits;
 
     if (!info) {
        num_info = 1;
@@ -2550,9 +2550,9 @@ yasm_x86__finalize_insn(yasm_arch *arch, yasm_bytecode *bc,
            /* Check for 64-bit effective address size in NASM mode */
            if (suffix == 0 && op->type == YASM_INSN__OPERAND_MEMORY) {
                if ((info->operands[i] & OPEAS_MASK) == OPEAS_64) {
-                   if (op->data.ea->disp_len != 8)
+                   if (op->data.ea->disp.size != 64)
                        mismatch = 1;
-               } else if (op->data.ea->disp_len == 8)
+               } else if (op->data.ea->disp.size == 64)
                    mismatch = 1;
            }
 
@@ -2694,7 +2694,7 @@ yasm_x86__finalize_insn(yasm_arch *arch, yasm_bytecode *bc,
     if (info->modifiers & MOD_Imm8) {
        imm = yasm_expr_create_ident(yasm_expr_int(
            yasm_intnum_create_uint(mod_data & 0xFF)), bc->line);
-       im_len = 1;
+       im_len = 8;
        mod_data >>= 8;
     }
     if (info->modifiers & MOD_DOpS64R) {
@@ -2868,7 +2868,7 @@ yasm_x86__finalize_insn(yasm_arch *arch, yasm_bytecode *bc,
     }
     if (imm) {
        insn->imm = yasm_imm_create_expr(imm);
-       insn->imm->len = im_len;
+       insn->imm->val.size = im_len;
        insn->imm->sign = im_sign;
     } else
        insn->imm = NULL;
index 96bda2c688f9938e23d6746314f06d5742a16bd8..dc0c3ab4ab275f61805ef3cf32e03d25f2ada96c 100644 (file)
@@ -662,15 +662,15 @@ cv_out_sym(yasm_symrec *sym, unsigned long off, yasm_bytecode *bc,
     yasm_value val;
 
     /* sym in its section */
-    yasm_value_init_sym(&val, sym);
+    yasm_value_init_sym(&val, sym, 32);
     val.section_rel = 1;
-    output_value(&val, *bufp, 4, 32, 0, off, bc, 0, d);
+    output_value(&val, *bufp, 4, off, bc, 0, d);
     *bufp += 4;
 
     /* section index */
-    yasm_value_init_sym(&val, sym);
+    yasm_value_init_sym(&val, sym, 16);
     val.seg_of = 1;
-    output_value(&val, *bufp, 2, 16, 0, off+4, bc, 0, d);
+    output_value(&val, *bufp, 2, off+4, bc, 0, d);
     *bufp += 2;
 }
 
index dfddc492e1fd700ac50bb95d25822b978d8df6fa..f9e9dac5c907a9626f2ce69132aab2241a7d2cbf 100644 (file)
@@ -291,9 +291,9 @@ dwarf2_head_bc_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
        yasm_value value;
        yasm_value_init_sym(&value,
            yasm_dwarf2__bc_sym(dbgfmt_dwarf2->symtab,
-                               yasm_section_bcs_first(head->debug_ptr)));
+                               yasm_section_bcs_first(head->debug_ptr)),
+           dbgfmt_dwarf2->sizeof_offset*8);
        output_value(&value, buf, dbgfmt_dwarf2->sizeof_offset,
-                    dbgfmt_dwarf2->sizeof_offset*8, 0,
                     (unsigned long)(buf-*bufp), bc, 0, d);
        buf += dbgfmt_dwarf2->sizeof_offset;
     }
index 5be6581e3a82e6d39935c2bf8ce680d09df4a9dd..5245a73ca147f60b43c808a42d26de420d9f72b4 100644 (file)
@@ -806,9 +806,9 @@ dwarf2_line_op_bc_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
        YASM_WRITE_8(buf, line_op->ext_opcode);
        if (line_op->ext_operand) {
            yasm_value value;
-           yasm_value_init_sym(&value, line_op->ext_operand);
+           yasm_value_init_sym(&value, line_op->ext_operand,
+                               line_op->ext_operandsize*8);
            output_value(&value, buf, line_op->ext_operandsize,
-                        line_op->ext_operandsize*8, 0,
                         (unsigned long)(buf-*bufp), bc, 0, d);
            buf += line_op->ext_operandsize;
        }
index 26ba22b6886c6b1a1b89767668e34cfe2dd9ece6..168e9ab5af7d990cf0255f6d6c50c04a2ad23ee8 100644 (file)
@@ -82,18 +82,18 @@ nasm_listfmt_destroy(/*@only@*/ yasm_listfmt *listfmt)
 
 static int
 nasm_listfmt_output_value(yasm_value *value, unsigned char *buf,
-                         size_t destsize, size_t valsize, int shift,
-                         unsigned long offset, yasm_bytecode *bc, int warn,
-                         /*@null@*/ void *d)
+                         size_t destsize, unsigned long offset,
+                         yasm_bytecode *bc, int warn, /*@null@*/ void *d)
 {
     /*@null@*/ nasm_listfmt_output_info *info = (nasm_listfmt_output_info *)d;
     /*@dependent@*/ /*@null@*/ yasm_intnum *intn;
+    unsigned int valsize = value->size;
 
     assert(info != NULL);
 
     /* Output */
-    switch (yasm_value_output_basic(value, buf, destsize, valsize, shift, bc,
-                                   warn, info->arch, NULL)) {
+    switch (yasm_value_output_basic(value, buf, destsize, bc, warn, info->arch,
+                                   NULL)) {
        case -1:
            return 1;
        case 0:
@@ -124,7 +124,7 @@ nasm_listfmt_output_value(yasm_value *value, unsigned char *buf,
        intn = yasm_expr_get_intnum(&value->abs, NULL);
        if (intn)
            return yasm_arch_intnum_tobytes(info->arch, intn, buf, destsize,
-                                           valsize, shift, bc, 0);
+                                           valsize, 0, bc, 0);
        else {
            yasm_error_set(YASM_ERROR_TOO_COMPLEX,
                           N_("relocation too complex"));
@@ -134,7 +134,7 @@ nasm_listfmt_output_value(yasm_value *value, unsigned char *buf,
        int retval;
        intn = yasm_intnum_create_uint(0);
        retval = yasm_arch_intnum_tobytes(info->arch, intn, buf, destsize,
-                                         valsize, shift, bc, 0);
+                                         valsize, 0, bc, 0);
        yasm_intnum_destroy(intn);
        return retval;
     }
index d5827efff72b2710f01fb59db5f6d0d35b547713..184656e0f28eb25053f9581ff7ec1b15ba437e66 100644 (file)
@@ -136,7 +136,6 @@ bin_objfmt_expr_xform(/*@returned@*/ /*@only@*/ yasm_expr *e,
 
 static int
 bin_objfmt_output_value(yasm_value *value, unsigned char *buf, size_t destsize,
-                       size_t valsize, int shift,
                        /*@unused@*/ unsigned long offset, yasm_bytecode *bc,
                        int warn, /*@null@*/ void *d)
 {
@@ -166,8 +165,8 @@ bin_objfmt_output_value(yasm_value *value, unsigned char *buf, size_t destsize,
            (value->abs, 1, 1, 1, NULL, bin_objfmt_expr_xform, NULL, NULL);
 
     /* Output */
-    switch (yasm_value_output_basic(value, buf, destsize, valsize, shift,
-                                   bc, warn, info->objfmt_bin->arch, NULL)) {
+    switch (yasm_value_output_basic(value, buf, destsize, bc, warn,
+                                   info->objfmt_bin->arch, NULL)) {
        case -1:
            return 1;
        case 0:
index 32affca88aac144de65ad1db5e4ce77205c27eb1..f9a3982d2a51d97e41cb334825c1371106c32d49 100644 (file)
@@ -425,8 +425,8 @@ coff_objfmt_set_section_addr(yasm_section *sect, /*@null@*/ void *d)
 
 static int
 coff_objfmt_output_value(yasm_value *value, unsigned char *buf, size_t destsize,
-                        size_t valsize, int shift, unsigned long offset,
-                        yasm_bytecode *bc, int warn, /*@null@*/ void *d)
+                        unsigned long offset, yasm_bytecode *bc, int warn,
+                        /*@null@*/ void *d)
 {
     /*@null@*/ coff_objfmt_output_info *info = (coff_objfmt_output_info *)d;
     yasm_objfmt_coff *objfmt_coff;
@@ -434,6 +434,7 @@ coff_objfmt_output_value(yasm_value *value, unsigned char *buf, size_t destsize,
     /*@dependent@*/ /*@null@*/ yasm_intnum *intn;
     unsigned long intn_val, intn_minus;
     int retval;
+    unsigned int valsize = value->size;
 
     assert(info != NULL);
     objfmt_coff = info->objfmt_coff;
@@ -445,8 +446,8 @@ coff_objfmt_output_value(yasm_value *value, unsigned char *buf, size_t destsize,
      * Note this does NOT output any value with a SEG, WRT, external,
      * cross-section, or non-PC-relative reference (those are handled below).
      */
-    switch (yasm_value_output_basic(value, buf, destsize, valsize, shift, bc,
-                                   warn, info->objfmt_coff->arch,
+    switch (yasm_value_output_basic(value, buf, destsize, bc, warn,
+                                   info->objfmt_coff->arch,
                                    yasm_common_calc_bc_dist)) {
        case -1:
            return 1;
@@ -679,7 +680,7 @@ coff_objfmt_output_value(yasm_value *value, unsigned char *buf, size_t destsize,
     }
 
     retval = yasm_arch_intnum_tobytes(objfmt_coff->arch, intn, buf, destsize,
-                                     valsize, shift, bc, warn);
+                                     valsize, 0, bc, warn);
     yasm_intnum_destroy(intn);
     return retval;
 }
index aab461e49a36ef70e686ae035dc385d5a6a4173c..b7d15fc6694fdf4bf2ebd80778beb7daf2b8e7ff 100644 (file)
@@ -293,14 +293,15 @@ elf_objfmt_output_reloc(yasm_symrec *sym, yasm_bytecode *bc,
 
 static int
 elf_objfmt_output_value(yasm_value *value, unsigned char *buf, size_t destsize,
-                       size_t valsize, int shift, unsigned long offset,
-                       yasm_bytecode *bc, int warn, /*@null@*/ void *d)
+                       unsigned long offset, yasm_bytecode *bc, int warn,
+                       /*@null@*/ void *d)
 {
     /*@null@*/ elf_objfmt_output_info *info = (elf_objfmt_output_info *)d;
     /*@dependent@*/ /*@null@*/ yasm_intnum *intn;
     unsigned long intn_val;
     /*@null@*/ elf_reloc_entry *reloc = NULL;
     int retval;
+    unsigned int valsize = value->size;
 
     if (info == NULL)
        yasm_internal_error("null info struct");
@@ -312,8 +313,8 @@ elf_objfmt_output_value(yasm_value *value, unsigned char *buf, size_t destsize,
      * Note this does NOT output any value with a SEG, WRT, external,
      * cross-section, or non-PC-relative reference (those are handled below).
      */
-    switch (yasm_value_output_basic(value, buf, destsize, valsize, shift, bc,
-                                   warn, info->objfmt_elf->arch,
+    switch (yasm_value_output_basic(value, buf, destsize, bc, warn,
+                                   info->objfmt_elf->arch,
                                    yasm_common_calc_bc_dist)) {
        case -1:
            return 1;
@@ -393,7 +394,7 @@ elf_objfmt_output_value(yasm_value *value, unsigned char *buf, size_t destsize,
     if (reloc)
        elf_handle_reloc_addend(intn, reloc);
     retval = yasm_arch_intnum_tobytes(info->objfmt_elf->arch, intn, buf,
-                                     destsize, valsize, shift, bc, warn);
+                                     destsize, valsize, 0, bc, warn);
     yasm_intnum_destroy(intn);
     return retval;
 }
index 8ebb6c4fa797d108da86b1acd257d9acd3ec1218..5a1b80023e7d1eec4af076877da0ed09e26115ac 100644 (file)
@@ -159,14 +159,15 @@ xdf_objfmt_create(yasm_object *object, yasm_arch *a)
 
 static int
 xdf_objfmt_output_value(yasm_value *value, unsigned char *buf, size_t destsize,
-                       size_t valsize, int shift, unsigned long offset,
-                       yasm_bytecode *bc, int warn, /*@null@*/ void *d)
+                       unsigned long offset, yasm_bytecode *bc, int warn,
+                       /*@null@*/ void *d)
 {
     /*@null@*/ xdf_objfmt_output_info *info = (xdf_objfmt_output_info *)d;
     yasm_objfmt_xdf *objfmt_xdf;
     /*@dependent@*/ /*@null@*/ yasm_intnum *intn;
     unsigned long intn_minus;
     int retval;
+    unsigned int valsize = value->size;
 
     assert(info != NULL);
     objfmt_xdf = info->objfmt_xdf;
@@ -178,8 +179,8 @@ xdf_objfmt_output_value(yasm_value *value, unsigned char *buf, size_t destsize,
      * Note this does NOT output any value with a SEG, WRT, external,
      * cross-section, or non-PC-relative reference (those are handled below).
      */
-    switch (yasm_value_output_basic(value, buf, destsize, valsize, shift, bc,
-                                   warn, info->objfmt_xdf->arch,
+    switch (yasm_value_output_basic(value, buf, destsize, bc, warn,
+                                   info->objfmt_xdf->arch,
                                    yasm_common_calc_bc_dist)) {
        case -1:
            return 1;
@@ -241,7 +242,7 @@ xdf_objfmt_output_value(yasm_value *value, unsigned char *buf, size_t destsize,
     }
 
     retval = yasm_arch_intnum_tobytes(objfmt_xdf->arch, intn, buf, destsize,
-                                     valsize, shift, bc, warn);
+                                     valsize, 0, bc, warn);
     yasm_intnum_destroy(intn);
     return retval;
 }
index 2dcb2a5f30724eda0bbe225735be1166ff75230b..0eba1c8ff48ac3cd1ea0e3da77bfcc25d58fb770 100644 (file)
@@ -336,7 +336,7 @@ lineexp: instr
        $$ = yasm_bc_create_data(&$2, 2, 0, parser_gas->arch, cur_line);
     }
     | DIR_WORD datavals {
-       $$ = yasm_bc_create_data(&$2, yasm_arch_wordsize(parser_gas->arch), 0,
+       $$ = yasm_bc_create_data(&$2, yasm_arch_wordsize(parser_gas->arch)/8, 0,
                                 parser_gas->arch, cur_line);
     }
     | DIR_INT datavals {
index 65c4c733066f901d5b7ef103d5df70328155699d..ab5c0b67e7390f4a581204e8b241b435bfb59388 100644 (file)
@@ -197,10 +197,10 @@ lineexp: exp
 
 exp: instr
     | DECLARE_DATA datavals            {
-       $$ = yasm_bc_create_data(&$2, $1, 0, parser_nasm->arch, cur_line);
+       $$ = yasm_bc_create_data(&$2, $1/8, 0, parser_nasm->arch, cur_line);
     }
     | RESERVE_SPACE expr               {
-       $$ = yasm_bc_create_reserve($2, $1, cur_line);
+       $$ = yasm_bc_create_reserve($2, $1/8, cur_line);
     }
     | INCBIN STRING                    {
        $$ = yasm_bc_create_incbin($2.contents, NULL, NULL, cur_line);
index 891bef4ee3f5795c3ded7a1dcfc39f5d199fd065..b529e35099827c8c6a86213c429e20b5fe5f50bf 100644 (file)
@@ -249,7 +249,7 @@ scan:
        }
 
        /* size specifiers */
-       'byte'          { lvalp->int_info = 1; RETURN(SIZE_OVERRIDE); }
+       'byte'          { lvalp->int_info = 8; RETURN(SIZE_OVERRIDE); }
        'hword'         {
            lvalp->int_info = yasm_arch_wordsize(parser_nasm->arch)/2;
            RETURN(SIZE_OVERRIDE);
@@ -266,14 +266,14 @@ scan:
            lvalp->int_info = yasm_arch_wordsize(parser_nasm->arch)*4;
            RETURN(SIZE_OVERRIDE);
        }
-       'tword'         { lvalp->int_info = 10; RETURN(SIZE_OVERRIDE); }
+       'tword'         { lvalp->int_info = 80; RETURN(SIZE_OVERRIDE); }
        'dqword'        {
            lvalp->int_info = yasm_arch_wordsize(parser_nasm->arch)*8;
            RETURN(SIZE_OVERRIDE);
        }
 
        /* pseudo-instructions */
-       'db'            { lvalp->int_info = 1; RETURN(DECLARE_DATA); }
+       'db'            { lvalp->int_info = 8; RETURN(DECLARE_DATA); }
        'dhw'           {
            lvalp->int_info = yasm_arch_wordsize(parser_nasm->arch)/2;
            RETURN(DECLARE_DATA);
@@ -290,13 +290,13 @@ scan:
            lvalp->int_info = yasm_arch_wordsize(parser_nasm->arch)*4;
            RETURN(DECLARE_DATA);
        }
-       'dt'            { lvalp->int_info = 10; RETURN(DECLARE_DATA); }
+       'dt'            { lvalp->int_info = 80; RETURN(DECLARE_DATA); }
        'ddq'           {
            lvalp->int_info = yasm_arch_wordsize(parser_nasm->arch)*8;
            RETURN(DECLARE_DATA);
        }
 
-       'resb'          { lvalp->int_info = 1; RETURN(RESERVE_SPACE); }
+       'resb'          { lvalp->int_info = 8; RETURN(RESERVE_SPACE); }
        'reshw'         {
            lvalp->int_info = yasm_arch_wordsize(parser_nasm->arch)/2;
            RETURN(RESERVE_SPACE);
@@ -313,7 +313,7 @@ scan:
            lvalp->int_info = yasm_arch_wordsize(parser_nasm->arch)*4;
            RETURN(RESERVE_SPACE);
        }
-       'rest'          { lvalp->int_info = 10; RETURN(RESERVE_SPACE); }
+       'rest'          { lvalp->int_info = 80; RETURN(RESERVE_SPACE); }
        'resdq'         {
            lvalp->int_info = yasm_arch_wordsize(parser_nasm->arch)*8;
            RETURN(RESERVE_SPACE);
index dc3562c6de19223a5840ba780700c8493132d8e5..c0aabcad6c931e82d4c2650d5e6199f6300222ca 100644 (file)
@@ -64,6 +64,7 @@ cdef extern from "libyasm/coretype.h":
         unsigned int curpos_rel
         unsigned int ip_rel
         unsigned int section_rel
+        unsigned int size
 
     cdef struct yasm_linemap
     cdef struct yasm_valparam
@@ -115,8 +116,8 @@ cdef extern from "libyasm/coretype.h":
     ctypedef yasm_intnum*(*yasm_calc_bc_dist_func)(yasm_bytecode *precbc1,
             yasm_bytecode *precbc2)
     ctypedef int*(*yasm_output_value_func)(yasm_value *value, unsigned char
-            *buf, size_t destsize, size_t valsize, int shift, unsigned
-            long offset, yasm_bytecode *bc, int warn, void *d)
+            *buf, size_t destsize, unsigned long offset, yasm_bytecode *bc,
+            int warn, void *d)
     ctypedef int(*yasm_output_reloc_func)(yasm_symrec *sym,
             yasm_bytecode *bc, unsigned char *buf, size_t destsize,
             size_t valsize, int warn, void *d)
index 41461c3fa252f892bffdfa0e3662161f0119ef53..81b1f2dfa2928161dd5303eb971a611b5bb75a8b 100644 (file)
 # POSSIBILITY OF SUCH DAMAGE.
 
 cdef extern from "libyasm/value.h":
-    cdef void yasm_value_initialize(yasm_value *value, yasm_expr *e)
-    cdef void yasm_value_init_sym(yasm_value *value, yasm_symrec *sym)
+    cdef void yasm_value_initialize(yasm_value *value, yasm_expr *e,
+                                    unsigned int size)
+    cdef void yasm_value_init_sym(yasm_value *value, yasm_symrec *sym,
+                                  unsigned int size)
     cdef void yasm_value_delete(yasm_value *value)
     cdef int yasm_value_finalize(yasm_value *value)
-    cdef int yasm_value_finalize_expr(yasm_value *value, yasm_expr *e)
+    cdef int yasm_value_finalize_expr(yasm_value *value, yasm_expr *e,
+                                      unsigned int size)
     cdef int yasm_value_output_basic(yasm_value *value, unsigned char *buf,
-            size_t destsize, size_t valsize, int shift, yasm_bytecode *bc,
-            int warn, yasm_arch *arch, yasm_calc_bc_dist_func calc_bc_dist)
+            size_t destsize, yasm_bytecode *bc, int warn, yasm_arch *arch,
+            yasm_calc_bc_dist_func calc_bc_dist)
     cdef void yasm_value_print(yasm_value *value, FILE *f, int indent_level)
 
 cdef class Value:
     cdef yasm_value value
-    def __new__(self, value=None):
-        yasm_value_initialize(&self.value, NULL)
+    def __new__(self, value=None, size=None):
+        cdef unsigned int sz
+        if size is None:
+            sz = 0
+        else:
+            sz = size;
+
+        yasm_value_initialize(&self.value, NULL, sz)
         if value is None:
             pass
         elif isinstance(value, Expression):
             yasm_value_initialize(&self.value,
-                                  yasm_expr_copy((<Expression>value).expr))
+                                  yasm_expr_copy((<Expression>value).expr), sz)
         elif isinstance(value, Symbol):
-            yasm_value_init_sym(&self.value, (<Symbol>value).sym)
+            yasm_value_init_sym(&self.value, (<Symbol>value).sym, sz)
         else:
             raise ValueError("Invalid value type '%s'" % type(value))