]> granicus.if.org Git - yasm/commitdiff
Merge [1270] - [1332] (inclusive) into new-optimizer branch. It's going
authorPeter Johnson <peter@tortall.net>
Tue, 17 Jan 2006 07:54:30 +0000 (07:54 -0000)
committerPeter Johnson <peter@tortall.net>
Tue, 17 Jan 2006 07:54:30 +0000 (07:54 -0000)
to need some of these changes during implementation and testing.

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

1  2 
frontends/yasm/yasm.c
libyasm/bytecode.c
libyasm/bytecode.h
libyasm/section.c
libyasm/section.h
modules/arch/x86/x86arch.h
modules/arch/x86/x86bc.c
modules/arch/x86/x86id.re

Simple merge
index 73a0553f2645cee282f6c1bf55c42a74c47b31fd,0b120f1cb7076224c5f90360c5a20ebc83980b7a..d9968adbdb53a9f44ddd3cbaa1a3c04ebec63d7b
@@@ -125,12 -140,19 +142,23 @@@ static int bc_data_tobytes(yasm_bytecod
                           yasm_output_expr_func output_expr,
                           /*@null@*/ yasm_output_reloc_func output_reloc);
  
 -static yasm_bc_resolve_flags bc_leb128_resolve
 -    (yasm_bytecode *bc, int save, yasm_calc_bc_dist_func calc_bc_dist);
+ static void bc_leb128_destroy(void *contents);
+ static void bc_leb128_print(const void *contents, FILE *f, int indent_level);
+ static void bc_leb128_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc);
++static int bc_leb128_calc_len
++    (yasm_bytecode *bc, /*@out@*/ unsigned long *long_len,
++     /*@out@*/ /*@only@*/ yasm_expr **critical, /*@out@*/ long *neg_thres,
++     /*@out@*/ long *pos_thres);
+ static int bc_leb128_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
+                            yasm_output_expr_func output_expr,
+                            /*@null@*/ yasm_output_reloc_func output_reloc);
  static void bc_reserve_destroy(void *contents);
  static void bc_reserve_print(const void *contents, FILE *f, int indent_level);
 -static yasm_bc_resolve_flags bc_reserve_resolve
 -    (yasm_bytecode *bc, int save, yasm_calc_bc_dist_func calc_bc_dist);
 +static int bc_reserve_calc_len
 +    (yasm_bytecode *bc, /*@out@*/ unsigned long *long_len,
 +     /*@out@*/ /*@only@*/ yasm_expr **critical, /*@out@*/ long *neg_thres,
 +     /*@out@*/ long *pos_thres);
  static int bc_reserve_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
                              yasm_output_expr_func output_expr,
                              /*@null@*/ yasm_output_reloc_func output_reloc);
@@@ -188,6 -201,14 +216,15 @@@ static const yasm_bytecode_callback bc_
      bc_data_tobytes
  };
  
 -    bc_leb128_resolve,
+ static const yasm_bytecode_callback bc_leb128_callback = {
+     bc_leb128_destroy,
+     bc_leb128_print,
+     bc_leb128_finalize,
++    bc_leb128_calc_len,
++    yasm_bc_set_long_common,
+     bc_leb128_tobytes
+ };
  static const yasm_bytecode_callback bc_reserve_callback = {
      bc_reserve_destroy,
      bc_reserve_print,
@@@ -429,9 -439,11 +466,11 @@@ bc_data_calc_len(yasm_bytecode *bc, uns
                bc->len += slen*bc_data->size;
                break;
        }
+       if (bc_data->append_zero)
+           bc->len++;
      }
  
 -    return YASM_BC_RESOLVE_MIN_LEN;
 +    return 0;
  }
  
  static int
@@@ -486,6 -501,112 +528,112 @@@ yasm_bc_create_data(yasm_datavalhead *d
      return yasm_bc_create_common(&bc_data_callback, data, line);
  }
  
 -static yasm_bc_resolve_flags
 -bc_leb128_resolve(yasm_bytecode *bc, int save,
 -                yasm_calc_bc_dist_func calc_bc_dist)
+ static void
+ bc_leb128_destroy(void *contents)
+ {
+     bytecode_leb128 *bc_leb128 = (bytecode_leb128 *)contents;
+     yasm_dvs_destroy(&bc_leb128->datahead);
+     yasm_xfree(contents);
+ }
+ static void
+ bc_leb128_print(const void *contents, FILE *f, int indent_level)
+ {
+     const bytecode_leb128 *bc_leb128 = (const bytecode_leb128 *)contents;
+     fprintf(f, "%*s_Data_\n", indent_level, "");
+     fprintf(f, "%*sSign=%u\n", indent_level+1, "",
+           (unsigned int)bc_leb128->sign);
+     fprintf(f, "%*sElements:\n", indent_level+1, "");
+     yasm_dvs_print(&bc_leb128->datahead, f, indent_level+2);
+ }
+ static void
+ bc_leb128_finalize(yasm_bytecode *bc, yasm_bytecode *prev_bc)
+ {
+     bytecode_leb128 *bc_leb128 = (bytecode_leb128 *)bc->contents;
+     yasm_dataval *dv;
+     /*@dependent@*/ /*@null@*/ yasm_intnum *intn;
+     /* Only constant expressions are allowed.
+      * Because of this, go ahead and calculate length.
+      */
+     bc_leb128->len = 0;
+     STAILQ_FOREACH(dv, &bc_leb128->datahead, link) {
+       switch (dv->type) {
+           case DV_EMPTY:
+               break;
+           case DV_EXPR:
+               intn = yasm_expr_get_intnum(&dv->data.expn, NULL);
+               if (!intn) {
+                   yasm__error(bc->line,
+                               N_("LEB128 requires constant values"));
+                   return;
+               }
+               /* Warn for negative values in unsigned environment.
+                * This could be an error instead: the likelihood this is
+                * desired is very low!
+                */
+               if (yasm_intnum_sign(intn) == -1 && !bc_leb128->sign)
+                   yasm__warning(YASM_WARN_GENERAL, bc->line,
+                                 N_("negative value in unsigned LEB128"));
+               bc_leb128->len +=
+                   yasm_intnum_size_leb128(intn, bc_leb128->sign);
+               break;
+           case DV_STRING:
+               yasm__error(bc->line,
+                           N_("LEB128 does not allow string constants"));
+               return;
+       }
+     }
+ }
 -    return YASM_BC_RESOLVE_MIN_LEN;
++static int
++bc_leb128_calc_len(yasm_bytecode *bc, unsigned long *long_len,
++                 yasm_expr **critical, long *neg_thres, long *pos_thres)
+ {
+     bytecode_leb128 *bc_leb128 = (bytecode_leb128 *)bc->contents;
+     bc->len += bc_leb128->len;
++    return 0;
+ }
+ static int
+ bc_leb128_tobytes(yasm_bytecode *bc, unsigned char **bufp, void *d,
+                 yasm_output_expr_func output_expr,
+                 /*@unused@*/ yasm_output_reloc_func output_reloc)
+ {
+     bytecode_leb128 *bc_leb128 = (bytecode_leb128 *)bc->contents;
+     yasm_dataval *dv;
+     /*@dependent@*/ /*@null@*/ yasm_intnum *intn;
+     STAILQ_FOREACH(dv, &bc_leb128->datahead, link) {
+       switch (dv->type) {
+           case DV_EMPTY:
+               break;
+           case DV_EXPR:
+               intn = yasm_expr_get_intnum(&dv->data.expn, NULL);
+               if (!intn)
+                   yasm_internal_error(N_("non-constant in leb128_tobytes"));
+               *bufp += yasm_intnum_get_leb128(intn, *bufp, bc_leb128->sign);
+               break;
+           case DV_STRING:
+               yasm_internal_error(N_("string in leb128_tobytes"));
+       }
+     }
+     return 0;
+ }
+ yasm_bytecode *
+ yasm_bc_create_leb128(yasm_datavalhead *datahead, int sign, unsigned long line)
+ {
+     bytecode_leb128 *leb128 = yasm_xmalloc(sizeof(bytecode_leb128));
+     leb128->datahead = *datahead;
+     leb128->sign = sign;
+     return yasm_bc_create_common(&bc_leb128_callback, leb128, line);
+ }
  static void
  bc_reserve_destroy(void *contents)
  {
@@@ -1172,27 -1324,33 +1339,26 @@@ yasm_bc_calc_len(yasm_bytecode *bc, /*@
      if (!bc->callback)
        yasm_internal_error(N_("got empty bytecode in bc_resolve"));
      else
 -      retval = bc->callback->resolve(bc, save, calc_bc_dist);
 +      retval = bc->callback->calc_len(bc, long_len, critical, neg_thres,
 +                                      pos_thres);
  
 -    /* Multiply len by number of multiples */
 +    /* Check for multiples */
      if (bc->multiple) {
-       /*@null@*/ yasm_expr *temp;
 -      if (save) {
 -          temp = NULL;
 -          tempp = &bc->multiple;
 -      } else {
 -          temp = yasm_expr_copy(bc->multiple);
 -          assert(temp != NULL);
 -          tempp = &temp;
 -      }
 -      num = yasm_expr_get_intnum(tempp, calc_bc_dist);
 +      /*@dependent@*/ /*@null@*/ const yasm_intnum *num;
 +
 +      num = yasm_expr_get_intnum(&bc->multiple, NULL);
        if (!num) {
 -          retval = YASM_BC_RESOLVE_UNKNOWN_LEN;
 -          if (temp && yasm_expr__contains(temp, YASM_EXPR_FLOAT)) {
 +          if (yasm_expr__contains(bc->multiple, YASM_EXPR_FLOAT)) {
                yasm__error(bc->line,
                    N_("expression must not contain floating point value"));
 -              retval |= YASM_BC_RESOLVE_ERROR;
 +              retval = -1;
 +          } else {
 +              /* FIXME: Non-constant currently not allowed. */
 +              yasm__error(bc->line,
 +                          N_("attempt to use non-constant multiple"));
 +              retval = -1;
            }
 -      } else {
 -          if (yasm_intnum_sign(num) >= 0)
 -              bc->len *= yasm_intnum_get_uint(num);
 -          else
 -              retval |= YASM_BC_RESOLVE_ERROR;
        }
 -      yasm_expr_destroy(temp);
      }
  
      /* If we got an error somewhere along the line, clear out any calc len */
Simple merge
Simple merge
Simple merge
index 910497257365ad706cbec41a02356c94c9637501,03fb75d346d1792b0a5e6fdd5eb875b38f75637b..7065f4879c85a50ee243fc894ec18c3c5cbdb8ef
@@@ -214,7 -216,14 +216,15 @@@ typedef struct x86_insn 
        /* Override any attempt at address-size override to 16 bits, and never
         * generate a prefix.  This is used for the ENTER opcode.
         */
-       X86_POSTOP_ADDRESS16
+       X86_POSTOP_ADDRESS16,
+       /* Used for 64-bit mov immediate, which can take a sign-extended
+        * imm32 as well as imm64 values.  The imm32 form is put in the
+        * second byte of the opcode and its ModRM byte is put in the third
+        * byte of the opcode.
++       * FIXME: Update for new optimizer.
+        */
+       X86_POSTOP_SIGNEXT_IMM32
      } postop;
  } x86_insn;
  
Simple merge
Simple merge