From: Peter Johnson Date: Wed, 10 May 2006 08:54:52 +0000 (-0000) Subject: * coretype.h (yasm_value): Add size field (specified in bits). X-Git-Tag: v0.5.0~9^2~2 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=83c0ecaaecd05065f0cdebdce8b2950a5a9070be;p=yasm * coretype.h (yasm_value): Add size field (specified in bits). (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 --- diff --git a/libyasm/arch.h b/libyasm/arch.h index 11402cbf..0d94c7b2 100644 --- a/libyasm/arch.h +++ b/libyasm/arch.h @@ -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. diff --git a/libyasm/bc-data.c b/libyasm/bc-data.c index 5fe15a23..a253534d 100644 --- a/libyasm/bc-data.c +++ b/libyasm/bc-data.c @@ -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; } diff --git a/libyasm/bc-incbin.c b/libyasm/bc-incbin.c index d9da18fc..fd7f79e3 100644 --- a/libyasm/bc-incbin.c +++ b/libyasm/bc-incbin.c @@ -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) diff --git a/libyasm/bc-insn.c b/libyasm/bc-insn.c index 531ba5da..48fb2112 100644 --- a/libyasm/bc-insn.c +++ b/libyasm/bc-insn.c @@ -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); } diff --git a/libyasm/bc-reserve.c b/libyasm/bc-reserve.c index 782fb0b6..9e1fa1a7 100644 --- a/libyasm/bc-reserve.c +++ b/libyasm/bc-reserve.c @@ -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) diff --git a/libyasm/bytecode.c b/libyasm/bytecode.c index 99a4c741..2ab884b0 100644 --- a/libyasm/bytecode.c +++ b/libyasm/bytecode.c @@ -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) diff --git a/libyasm/bytecode.h b/libyasm/bytecode.h index 1426968d..f8100da1 100644 --- a/libyasm/bytecode.h +++ b/libyasm/bytecode.h @@ -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); diff --git a/libyasm/coretype.h b/libyasm/coretype.h index aa5b8119..89e5ed35 100644 --- a/libyasm/coretype.h +++ b/libyasm/coretype.h @@ -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 diff --git a/libyasm/intnum.c b/libyasm/intnum.c index 120a7a67..160d5dd4 100644 --- a/libyasm/intnum.c +++ b/libyasm/intnum.c @@ -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; diff --git a/libyasm/value.c b/libyasm/value.c index bc80c196..5f02f5b4 100644 --- a/libyasm/value.c +++ b/libyasm/value.c @@ -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); } diff --git a/libyasm/value.h b/libyasm/value.h index 10f33b33..8687f9c8 100644 --- a/libyasm/value.h +++ b/libyasm/value.h @@ -43,9 +43,11 @@ * 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 diff --git a/modules/arch/lc3b/lc3barch.c b/modules/arch/lc3b/lc3barch.c index 9d5ef2b6..4792b070 100644 --- a/modules/arch/lc3b/lc3barch.c +++ b/modules/arch/lc3b/lc3barch.c @@ -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 }; diff --git a/modules/arch/lc3b/lc3bbc.c b/modules/arch/lc3b/lc3bbc.c index ba2517b3..59e607fa 100644 --- a/modules/arch/lc3b/lc3bbc.c +++ b/modules/arch/lc3b/lc3bbc.c @@ -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: diff --git a/modules/arch/lc3b/lc3bid.re b/modules/arch/lc3b/lc3bid.re index 584f1e87..0c7e82a4 100644 --- a/modules/arch/lc3b/lc3bid.re +++ b/modules/arch/lc3b/lc3bid.re @@ -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 && inum_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; } } diff --git a/modules/arch/lc3b/tests/lc3b-basic.asm b/modules/arch/lc3b/tests/lc3b-basic.asm index 93b6f40f..4cfa7754 100644 --- a/modules/arch/lc3b/tests/lc3b-basic.asm +++ b/modules/arch/lc3b/tests/lc3b-basic.asm @@ -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 diff --git a/modules/arch/lc3b/tests/lc3b-basic.errwarn b/modules/arch/lc3b/tests/lc3b-basic.errwarn index e69de29b..8a232a02 100644 --- a/modules/arch/lc3b/tests/lc3b-basic.errwarn +++ b/modules/arch/lc3b/tests/lc3b-basic.errwarn @@ -0,0 +1 @@ +-:2: warning: value does not fit in signed 5 bit field diff --git a/modules/arch/lc3b/tests/lc3b-basic.hex b/modules/arch/lc3b/tests/lc3b-basic.hex index d23ea431..9e90c961 100644 --- a/modules/arch/lc3b/tests/lc3b-basic.hex +++ b/modules/arch/lc3b/tests/lc3b-basic.hex @@ -4,7 +4,7 @@ f6 18 40 54 -76 +65 55 fd 05 diff --git a/modules/arch/x86/x86arch.c b/modules/arch/x86/x86arch.c index 6103fe37..52e486c1 100644 --- a/modules/arch/x86/x86arch.c +++ b/modules/arch/x86/x86arch.c @@ -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 }; diff --git a/modules/arch/x86/x86bc.c b/modules/arch/x86/x86bc.c index 4e2068d6..62ef563b 100644 --- a/modules/arch/x86/x86bc.c +++ b/modules/arch/x86/x86bc.c @@ -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; diff --git a/modules/arch/x86/x86expr.c b/modules/arch/x86/x86expr.c index 50185145..b83d7979 100644 --- a/modules/arch/x86/x86expr.c +++ b/modules/arch/x86/x86expr.c @@ -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; } } diff --git a/modules/arch/x86/x86id.c b/modules/arch/x86/x86id.c index 47cdb4ef..9dd2ac88 100644 --- a/modules/arch/x86/x86id.c +++ b/modules/arch/x86/x86id.c @@ -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; diff --git a/modules/dbgfmts/codeview/cv-symline.c b/modules/dbgfmts/codeview/cv-symline.c index 96bda2c6..dc0c3ab4 100644 --- a/modules/dbgfmts/codeview/cv-symline.c +++ b/modules/dbgfmts/codeview/cv-symline.c @@ -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; } diff --git a/modules/dbgfmts/dwarf2/dwarf2-dbgfmt.c b/modules/dbgfmts/dwarf2/dwarf2-dbgfmt.c index dfddc492..f9e9dac5 100644 --- a/modules/dbgfmts/dwarf2/dwarf2-dbgfmt.c +++ b/modules/dbgfmts/dwarf2/dwarf2-dbgfmt.c @@ -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; } diff --git a/modules/dbgfmts/dwarf2/dwarf2-line.c b/modules/dbgfmts/dwarf2/dwarf2-line.c index 5be6581e..5245a73c 100644 --- a/modules/dbgfmts/dwarf2/dwarf2-line.c +++ b/modules/dbgfmts/dwarf2/dwarf2-line.c @@ -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; } diff --git a/modules/listfmts/nasm/nasm-listfmt.c b/modules/listfmts/nasm/nasm-listfmt.c index 26ba22b6..168e9ab5 100644 --- a/modules/listfmts/nasm/nasm-listfmt.c +++ b/modules/listfmts/nasm/nasm-listfmt.c @@ -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; } diff --git a/modules/objfmts/bin/bin-objfmt.c b/modules/objfmts/bin/bin-objfmt.c index d5827eff..184656e0 100644 --- a/modules/objfmts/bin/bin-objfmt.c +++ b/modules/objfmts/bin/bin-objfmt.c @@ -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: diff --git a/modules/objfmts/coff/coff-objfmt.c b/modules/objfmts/coff/coff-objfmt.c index 32affca8..f9a3982d 100644 --- a/modules/objfmts/coff/coff-objfmt.c +++ b/modules/objfmts/coff/coff-objfmt.c @@ -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; } diff --git a/modules/objfmts/elf/elf-objfmt.c b/modules/objfmts/elf/elf-objfmt.c index aab461e4..b7d15fc6 100644 --- a/modules/objfmts/elf/elf-objfmt.c +++ b/modules/objfmts/elf/elf-objfmt.c @@ -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; } diff --git a/modules/objfmts/xdf/xdf-objfmt.c b/modules/objfmts/xdf/xdf-objfmt.c index 8ebb6c4f..5a1b8002 100644 --- a/modules/objfmts/xdf/xdf-objfmt.c +++ b/modules/objfmts/xdf/xdf-objfmt.c @@ -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; } diff --git a/modules/parsers/gas/gas-bison.y b/modules/parsers/gas/gas-bison.y index 2dcb2a5f..0eba1c8f 100644 --- a/modules/parsers/gas/gas-bison.y +++ b/modules/parsers/gas/gas-bison.y @@ -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 { diff --git a/modules/parsers/nasm/nasm-bison.y b/modules/parsers/nasm/nasm-bison.y index 65c4c733..ab5c0b67 100644 --- a/modules/parsers/nasm/nasm-bison.y +++ b/modules/parsers/nasm/nasm-bison.y @@ -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); diff --git a/modules/parsers/nasm/nasm-token.re b/modules/parsers/nasm/nasm-token.re index 891bef4e..b529e350 100644 --- a/modules/parsers/nasm/nasm-token.re +++ b/modules/parsers/nasm/nasm-token.re @@ -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); diff --git a/tools/python-yasm/coretype.pxi b/tools/python-yasm/coretype.pxi index dc3562c6..c0aabcad 100644 --- a/tools/python-yasm/coretype.pxi +++ b/tools/python-yasm/coretype.pxi @@ -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) diff --git a/tools/python-yasm/value.pxi b/tools/python-yasm/value.pxi index 41461c3f..81b1f2df 100644 --- a/tools/python-yasm/value.pxi +++ b/tools/python-yasm/value.pxi @@ -24,27 +24,36 @@ # 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((value).expr)) + yasm_expr_copy((value).expr), sz) elif isinstance(value, Symbol): - yasm_value_init_sym(&self.value, (value).sym) + yasm_value_init_sym(&self.value, (value).sym, sz) else: raise ValueError("Invalid value type '%s'" % type(value))