]> granicus.if.org Git - yasm/commitdiff
Fix LOTS of little nits. Primary changes:
authorPeter Johnson <peter@tortall.net>
Thu, 11 Oct 2001 05:34:50 +0000 (05:34 -0000)
committerPeter Johnson <peter@tortall.net>
Thu, 11 Oct 2001 05:34:50 +0000 (05:34 -0000)
 - New intnum module to replace using just unsigned long (for >32 bit values).
   Read values using BitVector instead of strtoul().
 - Brought both floatnum and intnum into expr (still need to integrate calc for
   floatnum).
 - Add traversal function to ternary tree (for use by symrec_foreach).
 - Change floatnum output interface from single/double/extended to byte size.
 - Try to make floatnum/intnum interfaces very similar.  Still needs work.
 - Add/fix *_print functions, including interating ones for sections/bytecodes.
 - Fix handling of $ and $$.  Both now are properly parsed and bytecode'd.
 - Print out all sections and symbol table in main() in preparation for work
   on "cleanup" functionality between parser and optimizer stages (really part
   of the parser stage).

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

47 files changed:
configure.ac
configure.in
frontends/yasm/yasm.c
libyasm/bytecode.c
libyasm/bytecode.h
libyasm/expr.c
libyasm/expr.h
libyasm/floatnum.c
libyasm/floatnum.h
libyasm/intnum.c [new file with mode: 0644]
libyasm/intnum.h [new file with mode: 0644]
libyasm/section.c
libyasm/section.h
libyasm/symrec.c
libyasm/symrec.h
libyasm/tests/floatnum_test.c
libyasm/util.h
modules/arch/x86/expr.c
modules/arch/x86/x86expr.c
modules/parsers/nasm/bison.y.in
modules/parsers/nasm/nasm-bison.y
modules/parsers/nasm/token.l.in
src/Makefile.am
src/arch/x86/expr.c
src/arch/x86/x86expr.c
src/bytecode.c
src/bytecode.h
src/expr.c
src/expr.h
src/floatnum.c
src/floatnum.h
src/intnum.c [new file with mode: 0644]
src/intnum.h [new file with mode: 0644]
src/main.c
src/parsers/nasm/bison.y.in
src/parsers/nasm/nasm-bison.y
src/parsers/nasm/token.l.in
src/section.c
src/section.h
src/strtoul.c [deleted file]
src/symrec.c
src/symrec.h
src/ternary.c
src/ternary.h
src/tests/floatnum_test.c
src/util.h
util.h

index 20c6bd52c0882941222d1159739492181691afe3..f8a1803b8af6b51c612a54c20d2288fdd790d81b 100644 (file)
@@ -117,7 +117,7 @@ AC_TYPE_SIZE_T
 AC_FUNC_VPRINTF
 AC_CHECK_FUNCS(memcpy toascii abort)
 AC_CHECK_FUNCS(strcasecmp stricmp strcmpi, break)
-AC_REPLACE_FUNCS(strsep strtoul)
+AC_REPLACE_FUNCS(strsep)
 
 AC_CHECK_HEADERS(limits.h sys/queue.h sys/cdefs.h)
 
index 20c6bd52c0882941222d1159739492181691afe3..f8a1803b8af6b51c612a54c20d2288fdd790d81b 100644 (file)
@@ -117,7 +117,7 @@ AC_TYPE_SIZE_T
 AC_FUNC_VPRINTF
 AC_CHECK_FUNCS(memcpy toascii abort)
 AC_CHECK_FUNCS(strcasecmp stricmp strcmpi, break)
-AC_REPLACE_FUNCS(strsep strtoul)
+AC_REPLACE_FUNCS(strsep)
 
 AC_CHECK_HEADERS(limits.h sys/queue.h sys/cdefs.h)
 
index 8e1e6b1f6851213e49e40c71ecd356e83c93d024..6cad2ab297c7ff13530c99511277d709af5bbee7 100644 (file)
@@ -45,6 +45,7 @@
 #include "globals.h"
 #include "options.h"
 #include "errwarn.h"
+#include "symrec.h"
 
 #include "bytecode.h"
 #include "section.h"
@@ -99,6 +100,8 @@ char help_tail[] = "\n"
 int
 main(int argc, char *argv[])
 {
+    sectionhead *sections;
+
     if (parse_cmdline(argc, argv, options, countof(options, opt_option)))
        return EXIT_FAILURE;
 
@@ -123,11 +126,15 @@ main(int argc, char *argv[])
     /* Get initial BITS setting from object format */
     mode_bits = dbg_objfmt.default_mode_bits;
 
-    nasm_parser.do_parse(&nasm_parser, &dbg_objfmt, in);
+    sections = nasm_parser.do_parse(&nasm_parser, &dbg_objfmt, in);
 
     if (OutputAllErrorWarning() > 0)
        return EXIT_FAILURE;
 
+    sections_print(sections);
+    printf("\n***Symbol Table***\n");
+    symrec_foreach((int (*) (symrec *))symrec_print);
+
     if (in_filename)
        free(in_filename);
     return EXIT_SUCCESS;
index 96620a1d469383e4d461dd023d87fca9eba7af27..24bf0b203ecdfe135c72183f234ad2b82dd6e5a3 100644 (file)
@@ -37,6 +37,7 @@
 
 #include "globals.h"
 #include "errwarn.h"
+#include "intnum.h"
 #include "floatnum.h"
 #include "expr.h"
 
@@ -73,11 +74,10 @@ struct immval {
 struct dataval {
     STAILQ_ENTRY(dataval) link;
 
-    enum { DV_EMPTY, DV_EXPR, DV_FLOAT, DV_STRING } type;
+    enum { DV_EMPTY, DV_EXPR, DV_STRING } type;
 
     union {
        expr *expn;
-       floatnum *flt;
        char *str_val;
     } data;
 };
@@ -229,7 +229,7 @@ immval_new_int(unsigned long int_val)
 {
     immval *im = xmalloc(sizeof(immval));
 
-    im->val = expr_new_ident(ExprInt(int_val));
+    im->val = expr_new_ident(ExprInt(intnum_new_int(int_val)));
 
     if ((int_val & 0xFF) == int_val)
        im->len = 1;
@@ -249,7 +249,7 @@ immval_new_expr(expr *expr_ptr)
     immval *im = xmalloc(sizeof(immval));
 
     im->val = expr_ptr;
-
+    im->len = 0;
     im->isneg = 0;
 
     return im;
@@ -486,46 +486,7 @@ bytecode_new_jmprel(targetval     *target,
 bytecode *
 bytecode_new_data(datavalhead *datahead, unsigned long size)
 {
-    bytecode *bc;
-    dataval *cur;
-
-    /* First check to see if all the data elements are valid for the size
-     * being set.
-     * Validity table:
-     *  db (1)  -> expr, string
-     *  dw (2)  -> expr, string
-     *  dd (4)  -> expr, float, string
-     *  dq (8)  -> expr, float, string
-     *  dt (10) -> float, string
-     *
-     * Once we calculate expr we'll have to validate it against the size
-     * and warn/error appropriately (symbol constants versus labels:
-     * constants (equ's) should always be legal, but labels should raise
-     * warnings when used in db or dq context at the minimum).
-     */
-    STAILQ_FOREACH(cur, datahead, link) {
-       switch (cur->type) {
-           case DV_EMPTY:
-           case DV_STRING:
-               /* string is valid in every size */
-               break;
-           case DV_FLOAT:
-               if (size == 1)
-                   Error(_("floating-point constant encountered in `%s'"),
-                         "DB");
-               else if (size == 2)
-                   Error(_("floating-point constant encountered in `%s'"),
-                         "DW");
-               break;
-           case DV_EXPR:
-               if (size == 10)
-                   Error(_("non-floating-point value encountered in `%s'"),
-                         "DT");
-               break;
-       }
-    }
-
-    bc = bytecode_new_common();
+    bytecode *bc = bytecode_new_common();
 
     bc->type = BC_DATA;
 
@@ -570,14 +531,14 @@ bytecode_print(bytecode *bc)
                printf("\n Disp=");
                expr_print(bc->data.insn.ea->disp);
                printf("\n");
-               printf(" Len=%u SegmentOv=%2x\n",
+               printf(" Len=%u SegmentOv=%02x\n",
                       (unsigned int)bc->data.insn.ea->len,
                       (unsigned int)bc->data.insn.ea->segment);
-               printf(" ModRM=%2x ValidRM=%u NeedRM=%u\n",
+               printf(" ModRM=%02x ValidRM=%u NeedRM=%u\n",
                       (unsigned int)bc->data.insn.ea->modrm,
                       (unsigned int)bc->data.insn.ea->valid_modrm,
                       (unsigned int)bc->data.insn.ea->need_modrm);
-               printf(" SIB=%2x ValidSIB=%u NeedSIB=%u\n",
+               printf(" SIB=%02x ValidSIB=%u NeedSIB=%u\n",
                       (unsigned int)bc->data.insn.ea->sib,
                       (unsigned int)bc->data.insn.ea->valid_sib,
                       (unsigned int)bc->data.insn.ea->need_sib);
@@ -595,16 +556,17 @@ bytecode_print(bytecode *bc)
                printf(" FLen=%u, FSign=%u\n",
                       (unsigned int)bc->data.insn.imm->f_len,
                       (unsigned int)bc->data.insn.imm->f_sign);
-               printf("Opcode: %2x %2x %2x OpLen=%u\n",
-                      (unsigned int)bc->data.insn.opcode[0],
-                      (unsigned int)bc->data.insn.opcode[1],
-                      (unsigned int)bc->data.insn.opcode[2],
-                      (unsigned int)bc->data.insn.opcode_len);
-               printf("AddrSize=%u OperSize=%u LockRepPre=%2x\n",
-                      (unsigned int)bc->data.insn.addrsize,
-                      (unsigned int)bc->data.insn.opersize,
-                      (unsigned int)bc->data.insn.lockrep_pre);
            }
+           printf("Opcode: %02x %02x %02x OpLen=%u\n",
+                  (unsigned int)bc->data.insn.opcode[0],
+                  (unsigned int)bc->data.insn.opcode[1],
+                  (unsigned int)bc->data.insn.opcode[2],
+                  (unsigned int)bc->data.insn.opcode_len);
+           printf("AddrSize=%u OperSize=%u LockRepPre=%02x ShiftOp=%u\n",
+                  (unsigned int)bc->data.insn.addrsize,
+                  (unsigned int)bc->data.insn.opersize,
+                  (unsigned int)bc->data.insn.lockrep_pre,
+                  (unsigned int)bc->data.insn.shift_op);
            break;
        case BC_JMPREL:
            printf("_Relative Jump_\n");
@@ -614,7 +576,7 @@ bytecode_print(bytecode *bc)
            if (!bc->data.jmprel.shortop.opcode_len == 0)
                printf(" None\n");
            else
-               printf(" Opcode: %2x %2x %2x OpLen=%u\n",
+               printf(" Opcode: %02x %02x %02x OpLen=%u\n",
                       (unsigned int)bc->data.jmprel.shortop.opcode[0],
                       (unsigned int)bc->data.jmprel.shortop.opcode[1],
                       (unsigned int)bc->data.jmprel.shortop.opcode[2],
@@ -622,7 +584,7 @@ bytecode_print(bytecode *bc)
            if (!bc->data.jmprel.nearop.opcode_len == 0)
                printf(" None\n");
            else
-               printf(" Opcode: %2x %2x %2x OpLen=%u\n",
+               printf(" Opcode: %02x %02x %02x OpLen=%u\n",
                       (unsigned int)bc->data.jmprel.nearop.opcode[0],
                       (unsigned int)bc->data.jmprel.nearop.opcode[1],
                       (unsigned int)bc->data.jmprel.nearop.opcode[2],
@@ -648,7 +610,7 @@ bytecode_print(bytecode *bc)
                    printf("UNKNOWN!!");
                    break;
            }
-           printf("\nAddrSize=%u OperSize=%u LockRepPre=%2x\n",
+           printf("\nAddrSize=%u OperSize=%u LockRepPre=%02x\n",
                   (unsigned int)bc->data.jmprel.addrsize,
                   (unsigned int)bc->data.jmprel.opersize,
                   (unsigned int)bc->data.jmprel.lockrep_pre);
@@ -690,24 +652,24 @@ bytecodes_append(bytecodehead *headp, bytecode *bc)
     return (bytecode *)NULL;
 }
 
-dataval *
-dataval_new_expr(expr *expn)
+void
+bytecodes_print(const bytecodehead *headp)
 {
-    dataval *retval = xmalloc(sizeof(dataval));
-
-    retval->type = DV_EXPR;
-    retval->data.expn = expn;
+    bytecode *cur;
 
-    return retval;
+    STAILQ_FOREACH(cur, headp, link) {
+       printf("---Next Bytecode---\n");
+       bytecode_print(cur);
+    }
 }
 
 dataval *
-dataval_new_float(floatnum *flt)
+dataval_new_expr(expr *expn)
 {
     dataval *retval = xmalloc(sizeof(dataval));
 
-    retval->type = DV_FLOAT;
-    retval->data.flt = flt;
+    retval->type = DV_EXPR;
+    retval->data.expn = expn;
 
     return retval;
 }
@@ -748,11 +710,6 @@ dataval_print(datavalhead *head)
                expr_print(cur->data.expn);
                printf("\n");
                break;
-           case DV_FLOAT:
-               printf(" Float=");
-               floatnum_print(cur->data.flt);
-               printf("\n");
-               break;
            case DV_STRING:
                printf(" String=%s\n", cur->data.str_val);
                break;
index 32ffa963b778617aad9db2ff928d152aff834a88..be485e4f655310bec37a47b6d7f60692910410b7 100644 (file)
@@ -129,6 +129,8 @@ void bytecode_print(bytecode *bc);
  */
 bytecode *bytecodes_append(bytecodehead *headp, bytecode *bc);
 
+void bytecodes_print(const bytecodehead *headp);
+
 dataval *dataval_new_expr(expr *expn);
 dataval *dataval_new_float(floatnum *flt);
 dataval *dataval_new_string(char *str_val);
index 911fe47dd75f1ae4e494f5cac1889ad456a607d5..252065f738b874426ff4d93aa996c0a79ef8b433 100644 (file)
 #define N_(String)     (String)
 #endif
 
+#include "bitvect.h"
+
 #include "globals.h"
 #include "errwarn.h"
+#include "intnum.h"
 #include "floatnum.h"
 #include "expr.h"
 #include "symrec.h"
@@ -61,7 +64,7 @@ struct ExprItem {
     union {
        symrec *sym;
        expr *expn;
-       unsigned long int_val;
+       intnum *intn;
        floatnum *flt;
     } data;
 };
@@ -69,6 +72,8 @@ struct ExprItem {
 struct expr {
     ExprItem left, right;
     ExprOp op;
+    char *filename;
+    unsigned long line;
 };
 
 /* allocate a new expression node, with children as defined.
@@ -93,6 +98,10 @@ expr_new(ExprItem *left, ExprOp op, ExprItem *right)
        InternalError(__LINE__, __FILE__,
                      _("Right side of expression must exist"));
     }
+
+    ptr->filename = xstrdup(in_filename);
+    ptr->line = line_number;
+
     return ptr;
 }
 
@@ -116,11 +125,11 @@ ExprExpr(expr *x)
 }
 
 ExprItem *
-ExprInt(unsigned long i)
+ExprInt(intnum *i)
 {
     ExprItem *e = xmalloc(sizeof(ExprItem));
     e->type = EXPR_INT;
-    e->data.int_val = i;
+    e->data.intn = i;
     return e;
 }
 
@@ -138,7 +147,7 @@ int
 expr_simplify(expr *e)
 {
     int simplified = 0;
-    unsigned long int_val;
+    ExprItem tmp;
 
     /* try to simplify the left side */
     if (e->left.type == EXPR_EXPR) {
@@ -150,14 +159,14 @@ expr_simplify(expr *e)
         * pull it up into the current node */
        while (e->left.type == EXPR_EXPR &&
               e->left.data.expn->op == EXPR_IDENT) {
-           ExprItem tmp;
-           e->left.type = e->left.data.expn->right.type;
            memcpy(&tmp, &(e->left.data.expn->right), sizeof(ExprItem));
            free(e->left.data.expn);
-           memcpy(&(e->left.data.int_val), &tmp, sizeof(ExprItem));
+           memcpy(&e->left, &tmp, sizeof(ExprItem));
            simplified = 1;
        }
-    } else if (e->left.type == EXPR_SYM) {
+    }
+#if 0
+    else if (e->left.type == EXPR_SYM) {
        /* try to get value of symbol */
        if (symrec_get_int_value(e->left.data.sym, &int_val, 0)) {
            e->left.type = EXPR_INT;
@@ -166,6 +175,7 @@ expr_simplify(expr *e)
            simplified = 1;
        }
     }
+#endif
 
     /* ditto on the right */
     if (e->right.type == EXPR_EXPR) {
@@ -174,14 +184,14 @@ expr_simplify(expr *e)
 
        while (e->right.type == EXPR_EXPR &&
               e->right.data.expn->op == EXPR_IDENT) {
-           ExprItem tmp;
-           e->right.type = e->right.data.expn->right.type;
            memcpy(&tmp, &(e->right.data.expn->right), sizeof(ExprItem));
            free(e->right.data.expn);
-           memcpy(&(e->right.data.int_val), &tmp, sizeof(ExprItem));
+           memcpy(&e->right, &tmp, sizeof(ExprItem));
            simplified = 1;
        }
-    } else if (e->right.type == EXPR_SYM) {
+    }
+#if 0
+    else if (e->right.type == EXPR_SYM) {
        if (symrec_get_int_value(e->right.data.sym, &int_val, 0)) {
            e->right.type = EXPR_INT;
            /* don't try to free the symrec here. */
@@ -189,139 +199,45 @@ expr_simplify(expr *e)
            simplified = 1;
        }
     }
-
-    if ((e->left.type == EXPR_INT || e->left.type == EXPR_NONE) &&
-       e->right.type == EXPR_INT && e->op != EXPR_IDENT) {
-       switch (e->op) {
-           case EXPR_ADD:
-               e->right.data.int_val = e->left.data.int_val +
-                                       e->right.data.int_val;
-               break;
-           case EXPR_SUB:
-               e->right.data.int_val = e->left.data.int_val -
-                                       e->right.data.int_val;
-               break;
-           case EXPR_MUL:
-               e->right.data.int_val = e->left.data.int_val *
-                                       e->right.data.int_val;
-               break;
-           case EXPR_DIV:
-               e->right.data.int_val = e->left.data.int_val /
-                                       e->right.data.int_val;
-               break;
-           case EXPR_MOD:
-               e->right.data.int_val = e->left.data.int_val %
-                                       e->right.data.int_val;
-               break;
-           case EXPR_NEG:
-               e->right.data.int_val = -(e->right.data.int_val);
-               break;
-           case EXPR_NOT:
-               e->right.data.int_val = ~(e->right.data.int_val);
-               break;
-           case EXPR_OR:
-               e->right.data.int_val = e->left.data.int_val |
-                                       e->right.data.int_val;
-               break;
-           case EXPR_AND:
-               e->right.data.int_val = e->left.data.int_val &
-                                       e->right.data.int_val;
-               break;
-           case EXPR_XOR:
-               e->right.data.int_val = e->left.data.int_val ^
-                                       e->right.data.int_val;
-               break;
-           case EXPR_SHL:
-               e->right.data.int_val = e->right.data.int_val <<
-                                       e->left.data.int_val;
-               break;
-           case EXPR_SHR:
-               e->right.data.int_val = e->right.data.int_val >>
-                                       e->left.data.int_val;
-               break;
-           case EXPR_LOR:
-               e->right.data.int_val = e->left.data.int_val ||
-                                       e->right.data.int_val;
-               break;
-           case EXPR_LAND:
-               e->right.data.int_val = e->left.data.int_val &&
-                                       e->right.data.int_val;
-               break;
-           case EXPR_LNOT:
-               e->right.data.int_val = !e->right.data.int_val;
-               break;
-           case EXPR_EQ:
-               e->right.data.int_val = e->right.data.int_val ==
-                                       e->left.data.int_val;
-               break;
-           case EXPR_LT:
-               e->right.data.int_val = e->right.data.int_val <
-                                       e->left.data.int_val;
-               break;
-           case EXPR_GT:
-               e->right.data.int_val = e->right.data.int_val >
-                                       e->left.data.int_val;
-               break;
-           case EXPR_LE:
-               e->right.data.int_val = e->right.data.int_val <=
-                                       e->left.data.int_val;
-               break;
-           case EXPR_GE:
-               e->right.data.int_val = e->right.data.int_val >=
-                                       e->left.data.int_val;
-               break;
-           case EXPR_NE:
-               e->right.data.int_val = e->right.data.int_val !=
-                                       e->left.data.int_val;
-               break;
-           case EXPR_IDENT:
-               break;
-       }
-       e->op = EXPR_IDENT;
-       simplified = 1;
-    }
+#endif
 
     /* catch simple identities like 0+x, 1*x, etc., for x not a num */
-    else if (e->left.type == EXPR_INT &&
-            ((e->left.data.int_val == 1 && e->op == EXPR_MUL) ||
-             (e->left.data.int_val == 0 && e->op == EXPR_ADD) ||
-             (e->left.data.int_val == -1 && e->op == EXPR_AND) ||
-             (e->left.data.int_val == 0 && e->op == EXPR_OR))) {
+    if (e->left.type == EXPR_INT &&
+            ((intnum_is_pos1(e->left.data.intn) && e->op == EXPR_MUL) ||
+             (intnum_is_zero(e->left.data.intn) && e->op == EXPR_ADD) ||
+             (intnum_is_neg1(e->left.data.intn) && e->op == EXPR_AND) ||
+             (intnum_is_zero(e->left.data.intn) && e->op == EXPR_OR))) {
+       intnum_delete(e->left.data.intn);
        e->op = EXPR_IDENT;
        simplified = 1;
     }
     /* and the corresponding x+|-0, x*&/1 */
     else if (e->right.type == EXPR_INT &&
-            ((e->right.data.int_val == 1 && e->op == EXPR_MUL) ||
-             (e->right.data.int_val == 1 && e->op == EXPR_DIV) ||
-             (e->right.data.int_val == 0 && e->op == EXPR_ADD) ||
-             (e->right.data.int_val == 0 && e->op == EXPR_SUB) ||
-             (e->right.data.int_val == -1 && e->op == EXPR_AND) ||
-             (e->right.data.int_val == 0 && e->op == EXPR_OR) ||
-             (e->right.data.int_val == 0 && e->op == EXPR_SHL) ||
-             (e->right.data.int_val == 0 && e->op == EXPR_SHR))) {
+            ((intnum_is_pos1(e->right.data.intn) && e->op == EXPR_MUL) ||
+             (intnum_is_pos1(e->right.data.intn) && e->op == EXPR_DIV) ||
+             (intnum_is_zero(e->right.data.intn) && e->op == EXPR_ADD) ||
+             (intnum_is_zero(e->right.data.intn) && e->op == EXPR_SUB) ||
+             (intnum_is_neg1(e->right.data.intn) && e->op == EXPR_AND) ||
+             (intnum_is_zero(e->right.data.intn) && e->op == EXPR_OR) ||
+             (intnum_is_zero(e->right.data.intn) && e->op == EXPR_SHL) ||
+             (intnum_is_zero(e->right.data.intn) && e->op == EXPR_SHR))) {
+       intnum_delete(e->right.data.intn);
        e->op = EXPR_IDENT;
        e->right.type = e->left.type;
        memcpy(&e->right, &e->left, sizeof(ExprItem));
        simplified = 1;
+    } else if ((e->left.type == EXPR_INT || e->left.type == EXPR_NONE) &&
+       e->right.type == EXPR_INT && e->op != EXPR_IDENT) {
+       intnum_calc(e->left.data.intn, e->op, e->right.data.intn);
+       intnum_delete(e->right.data.intn);
+       e->right.data.intn = e->left.data.intn;
+       e->op = EXPR_IDENT;
+       simplified = 1;
     }
 
     return simplified;
 }
 
-int
-expr_get_value(expr *e, unsigned long *retval)
-{
-    while (!(e->op == EXPR_IDENT && e->right.type == EXPR_INT)
-          && expr_simplify(e)) ;
-
-    if (e->op == EXPR_IDENT && e->right.type == EXPR_INT) {
-       *retval = e->right.data.int_val;
-       return 1;
-    } else
-       return 0;
-}
-
 void
 expr_print(expr *e)
 {
@@ -336,7 +252,7 @@ expr_print(expr *e)
                printf(")");
                break;
            case EXPR_INT:
-               printf("%lu", e->left.data.int_val);
+               intnum_print(e->left.data.intn);
                break;
            case EXPR_FLOAT:
                floatnum_print(e->left.data.flt);
@@ -358,9 +274,15 @@ expr_print(expr *e)
        case EXPR_DIV:
            printf("/");
            break;
+       case EXPR_SIGNDIV:
+           printf("//");
+           break;
        case EXPR_MOD:
            printf("%%");
            break;
+       case EXPR_SIGNMOD:
+           printf("%%%%");
+           break;
        case EXPR_NEG:
            printf("-");
            break;
@@ -422,7 +344,7 @@ expr_print(expr *e)
            printf(")");
            break;
        case EXPR_INT:
-           printf("%lu", e->right.data.int_val);
+           intnum_print(e->right.data.intn);
            break;
        case EXPR_FLOAT:
            floatnum_print(e->right.data.flt);
index 25a0bb48f92f234643a3f4a775b6b10ce8483cf2..8adad2db4e546b7facae7607fa85ec09fb4f8f20 100644 (file)
@@ -32,12 +32,21 @@ typedef struct symrec symrec;
 typedef struct floatnum floatnum;
 #endif
 
+#ifndef YASM_INTNUM
+#define YASM_INTNUM
+typedef struct intnum intnum;
+#endif
+
+#ifndef YASM_EXPROP
+#define YASM_EXPROP
 typedef enum {
     EXPR_ADD,
     EXPR_SUB,
     EXPR_MUL,
     EXPR_DIV,
+    EXPR_SIGNDIV,
     EXPR_MOD,
+    EXPR_SIGNMOD,
     EXPR_NEG,
     EXPR_NOT,
     EXPR_OR,
@@ -56,6 +65,7 @@ typedef enum {
     EXPR_NE,
     EXPR_IDENT                 /* if right is IDENT, then the entire expr is just a num */
 } ExprOp;
+#endif
 
 typedef struct ExprItem ExprItem;
 
@@ -68,7 +78,7 @@ expr *expr_new(ExprItem *, ExprOp, ExprItem *);
 
 ExprItem *ExprSym(symrec *);
 ExprItem *ExprExpr(expr *);
-ExprItem *ExprInt(unsigned long);
+ExprItem *ExprInt(intnum *);
 ExprItem *ExprFloat(floatnum *);
 
 #define expr_new_tree(l,o,r) \
@@ -81,7 +91,4 @@ ExprItem *ExprFloat(floatnum *);
 int expr_simplify(expr *);
 void expr_print(expr *);
 
-/* get the value if possible.  return value is IF POSSIBLE, not the val */
-int expr_get_value(expr *, unsigned long *);
-
 #endif
index d2e143ffe540e9d2a6352e7820abbbb70bfc9f42..30ae74141239ad2fca16a4382a90992299cb63b6 100644 (file)
@@ -498,20 +498,28 @@ floatnum_delete(floatnum *flt)
     free(flt);
 }
 
+void
+floatnum_calc(floatnum *acc, ExprOp op, floatnum *operand)
+{
+    if (op != EXPR_NEG)
+       Error(_("Unsupported floating-point arithmetic operation"));
+    else
+       acc->sign ^= 1;
+}
+
 int
 floatnum_get_int(unsigned long *ret_val, const floatnum *flt)
 {
     unsigned char t[4];
 
-    if (floatnum_get_single(t, flt))
+    if (floatnum_get_sized(t, flt, 4))
        return 1;
 
     LOAD_LONG(*ret_val, &t[0]);
     return 0;
 }
 
-/* Function used by single, double, and extended conversion routines to actually
- * perform the conversion.
+/* Function used by conversion routines to actually perform the conversion.
  *
  * ptr -> the array to return the little-endian floating point value into.
  * flt -> the floating point value to convert.
@@ -614,14 +622,8 @@ floatnum_get_common(unsigned char *ptr, const floatnum *flt, int byte_size,
  * e = bias 127 exponent
  * s = sign bit
  * m = mantissa bits, bit 23 is an implied one bit.
- */
-int
-floatnum_get_single(unsigned char *ptr, const floatnum *flt)
-{
-    return floatnum_get_common(ptr, flt, 4, 23, 1, 8);
-}
-
-/* IEEE-754 (Intel) "double precision" format:
+ *
+ * IEEE-754 (Intel) "double precision" format:
  * 64 bits:
  * bit 63       bit 51                                               bit 0
  * |            |                                                        |
@@ -630,14 +632,8 @@ floatnum_get_single(unsigned char *ptr, const floatnum *flt)
  * e = bias 1023 exponent.
  * s = sign bit.
  * m = mantissa bits.  Bit 52 is an implied one bit.
- */
-int
-floatnum_get_double(unsigned char *ptr, const floatnum *flt)
-{
-    return floatnum_get_common(ptr, flt, 8, 52, 1, 11);
-}
-
-/* IEEE-754 (Intel) "extended precision" format:
+ *
+ * IEEE-754 (Intel) "extended precision" format:
  * 80 bits:
  * bit 79            bit 63                           bit 0
  * |                 |                                    |
@@ -648,9 +644,34 @@ floatnum_get_double(unsigned char *ptr, const floatnum *flt)
  * s = sign (for mantissa)
  */
 int
-floatnum_get_extended(unsigned char *ptr, const floatnum *flt)
+floatnum_get_sized(unsigned char *ptr, const floatnum *flt, size_t size)
 {
-    return floatnum_get_common(ptr, flt, 10, 64, 0, 15);
+    switch (size) {
+       case 4:
+           return floatnum_get_common(ptr, flt, 4, 23, 1, 8);
+       case 8:
+           return floatnum_get_common(ptr, flt, 8, 52, 1, 11);
+       case 10:
+           return floatnum_get_common(ptr, flt, 10, 64, 0, 15);
+       default:
+           InternalError(__LINE__, __FILE__,
+                         _("Invalid float conversion size"));
+           return 1;       /* never reached, but silence GCC warning */
+    }
+}
+
+/* 1 if the size is valid, 0 if it isn't */
+int
+floatnum_check_size(const floatnum *flt, size_t size)
+{
+    switch (size) {
+       case 4:
+       case 8:
+       case 10:
+           return 1;
+       default:
+           return 0;
+    }
 }
 
 void
@@ -666,19 +687,19 @@ floatnum_print(const floatnum *flt)
     free(str);
 
     /* 32-bit (single precision) format */
-    printf("32-bit: %d: ", floatnum_get_single(out, flt));
+    printf("32-bit: %d: ", floatnum_get_sized(out, flt, 4));
     for (i=0; i<4; i++)
        printf("%02x ", out[i]);
     printf("\n");
 
     /* 64-bit (double precision) format */
-    printf("64-bit: %d: ", floatnum_get_double(out, flt));
+    printf("64-bit: %d: ", floatnum_get_sized(out, flt, 8));
     for (i=0; i<8; i++)
        printf("%02x ", out[i]);
     printf("\n");
 
     /* 80-bit (extended precision) format */
-    printf("80-bit: %d: ", floatnum_get_extended(out, flt));
+    printf("80-bit: %d: ", floatnum_get_sized(out, flt, 10));
     for (i=0; i<10; i++)
        printf("%02x ", out[i]);
     printf("\n");
index 612922497468264c37d61426e37f69f9aff908c8..4963e79a536ea3f4a33b618d3a99963730fefdb9 100644 (file)
 #ifndef YASM_FLOATNUM_H
 #define YASM_FLOATNUM_H
 
+#ifndef YASM_EXPROP
+#define YASM_EXPROP
+typedef enum {
+    EXPR_ADD,
+    EXPR_SUB,
+    EXPR_MUL,
+    EXPR_DIV,
+    EXPR_SIGNDIV,
+    EXPR_MOD,
+    EXPR_SIGNMOD,
+    EXPR_NEG,
+    EXPR_NOT,
+    EXPR_OR,
+    EXPR_AND,
+    EXPR_XOR,
+    EXPR_SHL,
+    EXPR_SHR,
+    EXPR_LOR,
+    EXPR_LAND,
+    EXPR_LNOT,
+    EXPR_LT,
+    EXPR_GT,
+    EXPR_EQ,
+    EXPR_LE,
+    EXPR_GE,
+    EXPR_NE,
+    EXPR_IDENT /* if right is IDENT, then the entire expr is just a num */
+} ExprOp;
+#endif
+
 #ifndef YASM_FLOATNUM
 #define YASM_FLOATNUM
 typedef struct floatnum floatnum;
@@ -32,7 +62,12 @@ typedef struct floatnum floatnum;
 floatnum *floatnum_new(const char *str);
 void floatnum_delete(floatnum *flt);
 
-/* The get functions return nonzero if flt can't fit into that size format. */
+/* calculation function: acc = acc op operand */
+void floatnum_calc(floatnum *acc, ExprOp op, floatnum *operand);
+
+/* The get functions return nonzero if flt can't fit into that size format:
+ * -1 if underflow occurred, 1 if overflow occurred.
+ */
 
 /* Essentially a convert to single-precision and return as 32-bit value.
  * The 32-bit value is a "standard" C value (eg, of unknown endian).
@@ -42,9 +77,13 @@ int floatnum_get_int(unsigned long *ret_val, const floatnum *flt);
 /* ptr will point to the Intel-format little-endian byte string after a
  * successful call (eg, [0] should be the first byte output to the file).
  */
-int floatnum_get_single(unsigned char *ptr, const floatnum *flt);
-int floatnum_get_double(unsigned char *ptr, const floatnum *flt);
-int floatnum_get_extended(unsigned char *ptr, const floatnum *flt);
+int floatnum_get_sized(unsigned char *ptr, const floatnum *flt, size_t size);
+
+/* Basic check to see if size is even valid for flt conversion (doesn't
+ * actually check for underflow/overflow but rather checks for size=4,8,10).
+ * Returns 1 if valid, 0 if not.
+ */
+int floatnum_check_size(const floatnum *flt, size_t size);
 
 void floatnum_print(const floatnum *flt);
 
diff --git a/libyasm/intnum.c b/libyasm/intnum.c
new file mode 100644 (file)
index 0000000..05f5303
--- /dev/null
@@ -0,0 +1,542 @@
+/* $IdPath$
+ * Integer number functions.
+ *
+ *  Copyright (C) 2001  Peter Johnson
+ *
+ *  This file is part of YASM.
+ *
+ *  YASM is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  YASM is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "util.h"
+
+#include <stdio.h>
+#include <ctype.h>
+
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <string.h>
+#endif
+
+#include <libintl.h>
+#define _(String)      gettext(String)
+
+#include "bitvect.h"
+#include "file.h"
+
+#include "errwarn.h"
+#include "intnum.h"
+
+RCSID("$IdPath$");
+
+#define BITVECT_ALLOC_SIZE     80
+
+struct intnum {
+    union val {
+       unsigned long ul;       /* integer value (for integers <=32 bits) */
+       intptr bv;              /* bit vector (for integers >32 bits) */
+    } val;
+    enum { INTNUM_UL, INTNUM_BV } type;
+    unsigned char origsize;    /* original (parsed) size, in bits */
+};
+
+intnum *
+intnum_new_dec(char *str)
+{
+    intnum *intn = xmalloc(sizeof(intnum));
+    wordptr bv;
+
+    intn->origsize = 0;            /* no reliable way to figure this out */
+
+    bv = BitVector_Create(BITVECT_ALLOC_SIZE, FALSE);
+    if (BitVector_from_Dec(bv, (unsigned char *)str) == ErrCode_Ovfl)
+       Warning(_("Numeric constant too large for internal format"));
+    if (Set_Max(bv) < 32) {
+       intn->type = INTNUM_UL;
+       intn->val.ul = BitVector_Chunk_Read(bv, 32, 0);
+       BitVector_Destroy(bv);
+    } else {
+       intn->type = INTNUM_BV;
+       intn->val.bv = bv;
+    }
+
+    return intn;
+}
+
+intnum *
+intnum_new_bin(char *str)
+{
+    intnum *intn = xmalloc(sizeof(intnum));
+    wordptr bv;
+
+    intn->origsize = strlen(str);
+
+    if(intn->origsize > BITVECT_ALLOC_SIZE)
+       Warning(_("Numeric constant too large for internal format"));
+
+    bv = BitVector_Create(BITVECT_ALLOC_SIZE, FALSE);
+    BitVector_from_Bin(bv, (unsigned char *)str);
+    if (Set_Max(bv) < 32) {
+       intn->type = INTNUM_UL;
+       intn->val.ul = BitVector_Chunk_Read(bv, 32, 0);
+       BitVector_Destroy(bv);
+    } else {
+       intn->type = INTNUM_BV;
+       intn->val.bv = bv;
+    }
+
+    return intn;
+}
+
+intnum *
+intnum_new_oct(char *str)
+{
+    intnum *intn = xmalloc(sizeof(intnum));
+    wordptr bv;
+
+    intn->origsize = strlen(str)*3;
+
+    if(intn->origsize > BITVECT_ALLOC_SIZE)
+       Warning(_("Numeric constant too large for internal format"));
+
+    bv = BitVector_Create(BITVECT_ALLOC_SIZE, FALSE);
+    BitVector_from_Oct(bv, (unsigned char *)str);
+    if (Set_Max(bv) < 32) {
+       intn->type = INTNUM_UL;
+       intn->val.ul = BitVector_Chunk_Read(bv, 32, 0);
+       BitVector_Destroy(bv);
+    } else {
+       intn->type = INTNUM_BV;
+       intn->val.bv = bv;
+    }
+
+    return intn;
+}
+
+intnum *
+intnum_new_hex(char *str)
+{
+    intnum *intn = xmalloc(sizeof(intnum));
+    wordptr bv;
+
+    intn->origsize = strlen(str)*4;
+
+    if(intn->origsize > BITVECT_ALLOC_SIZE)
+       Warning(_("Numeric constant too large for internal format"));
+
+    bv = BitVector_Create(BITVECT_ALLOC_SIZE, FALSE);
+    BitVector_from_Hex(bv, (unsigned char *)str);
+    if (Set_Max(bv) < 32) {
+       intn->type = INTNUM_UL;
+       intn->val.ul = BitVector_Chunk_Read(bv, 32, 0);
+       BitVector_Destroy(bv);
+    } else {
+       intn->type = INTNUM_BV;
+       intn->val.bv = bv;
+    }
+
+    return intn;
+}
+
+intnum *
+intnum_new_charconst_nasm(const char *str)
+{
+    intnum *intn = xmalloc(sizeof(intnum));
+    size_t len = strlen(str);
+
+    if (len > 4)
+       Warning(_("character constant too large, ignoring trailing characters"));
+
+    intn->val.ul = 0;
+    intn->type = INTNUM_UL;
+    intn->origsize = len*8;
+
+    switch (len) {
+       case 4:
+           intn->val.ul |= (unsigned long)str[3];
+           intn->val.ul <<= 8;
+       case 3:
+           intn->val.ul |= (unsigned long)str[2];
+           intn->val.ul <<= 8;
+       case 2:
+           intn->val.ul |= (unsigned long)str[1];
+           intn->val.ul <<= 8;
+       case 1:
+           intn->val.ul |= (unsigned long)str[0];
+    }
+
+    return intn;
+}
+
+intnum *
+intnum_new_int(unsigned long i)
+{
+    intnum *intn = xmalloc(sizeof(intnum));
+
+    intn->val.ul = i;
+    intn->type = INTNUM_UL;
+    intn->origsize = 0;
+
+    return intn;
+}
+
+void
+intnum_delete(intnum *intn)
+{
+    if (intn->type == INTNUM_BV)
+       BitVector_Destroy(intn->val.bv);
+    free(intn);
+}
+
+void
+intnum_calc(intnum *acc, ExprOp op, intnum *operand)
+{
+    wordptr result = (wordptr)NULL, op1 = (wordptr)NULL, op2 = (wordptr)NULL;
+    wordptr spare;
+    boolean carry;
+
+    /* upsize to bitvector op if one of two parameters is bitvector already.
+     * BitVector results must be calculated through intermediate storage.
+     */
+    if (acc->type == INTNUM_BV || (operand && operand->type == INTNUM_BV)) {
+       result = BitVector_Create(BITVECT_ALLOC_SIZE, FALSE);
+       spare = BitVector_Create(BITVECT_ALLOC_SIZE, FALSE);
+
+       if (acc->type == INTNUM_BV)
+           op1 = acc->val.bv;
+       else {
+           op1 = BitVector_Create(BITVECT_ALLOC_SIZE, TRUE);
+           BitVector_Chunk_Store(op1, 32, 0, acc->val.ul);
+       }
+
+       if (operand) {
+           if (operand->type == INTNUM_BV)
+               op2 = acc->val.bv;
+           else {
+               op2 = BitVector_Create(BITVECT_ALLOC_SIZE, TRUE);
+               BitVector_Chunk_Store(op2, 32, 0, operand->val.ul);
+           }
+       }
+    }
+
+    if (!operand && op != EXPR_NEG && op != EXPR_NOT && op != EXPR_LNOT)
+       InternalError(__LINE__, __FILE__, _("Operation needs an operand"));
+
+    /* A operation does a bitvector computation if result is allocated. */
+    switch (op) {
+       case EXPR_ADD:
+           if (result)
+               BitVector_add(result, op1, op2, &carry);
+           else
+               acc->val.ul = acc->val.ul + operand->val.ul;
+           break;
+       case EXPR_SUB:
+           if (result)
+               BitVector_sub(result, op1, op2, &carry);
+           else
+               acc->val.ul = acc->val.ul - operand->val.ul;
+           break;
+       case EXPR_MUL:
+           if (result)
+               /* TODO: Make sure result size = op1+op2 */
+               BitVector_Multiply(result, op1, op2);
+           else
+               acc->val.ul = acc->val.ul * operand->val.ul;
+           break;
+       case EXPR_DIV:
+           if (result) {
+               /* TODO: make sure op1 and op2 are unsigned */
+               BitVector_Divide(result, op1, op2, spare);
+           } else
+               acc->val.ul = acc->val.ul / operand->val.ul;
+           break;
+       case EXPR_SIGNDIV:
+           if (result)
+               BitVector_Divide(result, op1, op2, spare);
+           else
+               acc->val.ul = (unsigned long)((signed long)acc->val.ul /
+                                             (signed long)operand->val.ul);
+           break;
+       case EXPR_MOD:
+           if (result) {
+               /* TODO: make sure op1 and op2 are unsigned */
+               BitVector_Divide(spare, op1, op2, result);
+           } else
+               acc->val.ul = acc->val.ul % operand->val.ul;
+           break;
+       case EXPR_SIGNMOD:
+           if (result)
+               BitVector_Divide(spare, op1, op2, result);
+           else
+               acc->val.ul = (unsigned long)((signed long)acc->val.ul %
+                                             (signed long)operand->val.ul);
+           break;
+       case EXPR_NEG:
+           if (result)
+               BitVector_Negate(result, op1);
+           else
+               acc->val.ul = -(acc->val.ul);
+           break;
+       case EXPR_NOT:
+           if (result)
+               Set_Complement(result, op1);
+           else
+               acc->val.ul = ~(acc->val.ul);
+           break;
+       case EXPR_OR:
+           if (result)
+               Set_Union(result, op1, op2);
+           else
+               acc->val.ul = acc->val.ul | operand->val.ul;
+           break;
+       case EXPR_AND:
+           if (result)
+               Set_Intersection(result, op1, op2);
+           else
+               acc->val.ul = acc->val.ul & operand->val.ul;
+           break;
+       case EXPR_XOR:
+           if (result)
+               Set_ExclusiveOr(result, op1, op2);
+           else
+               acc->val.ul = acc->val.ul ^ operand->val.ul;
+           break;
+       case EXPR_SHL:
+           if (result) {
+               if (operand->type == INTNUM_UL) {
+                   BitVector_Copy(result, op1);
+                   BitVector_Move_Left(result, operand->val.ul);
+               } else  /* don't even bother, just zero result */
+                   BitVector_Empty(result);
+           } else
+               acc->val.ul = acc->val.ul << operand->val.ul;
+           break;
+       case EXPR_SHR:
+           if (result) {
+               if (operand->type == INTNUM_UL) {
+                   BitVector_Copy(result, op1);
+                   BitVector_Move_Right(result, operand->val.ul);
+               } else  /* don't even bother, just zero result */
+                   BitVector_Empty(result);
+           } else
+               acc->val.ul = acc->val.ul >> operand->val.ul;
+           break;
+       case EXPR_LOR:
+           if (result) {
+               BitVector_Empty(result);
+               BitVector_LSB(result, !BitVector_is_empty(op1) ||
+                             !BitVector_is_empty(op2));
+           } else
+               acc->val.ul = acc->val.ul || operand->val.ul;
+           break;
+       case EXPR_LAND:
+           if (result) {
+               BitVector_Empty(result);
+               BitVector_LSB(result, !BitVector_is_empty(op1) &&
+                             !BitVector_is_empty(op2));
+           } else
+               acc->val.ul = acc->val.ul && operand->val.ul;
+           break;
+       case EXPR_LNOT:
+           if (result) {
+               BitVector_Empty(result);
+               BitVector_LSB(result, BitVector_is_empty(op1));
+           } else
+               acc->val.ul = !acc->val.ul;
+           break;
+       case EXPR_EQ:
+           if (result) {
+               BitVector_Empty(result);
+               BitVector_LSB(result, BitVector_equal(op1, op2));
+           } else
+               acc->val.ul = acc->val.ul == operand->val.ul;
+           break;
+       case EXPR_LT:
+           if (result) {
+               BitVector_Empty(result);
+               BitVector_LSB(result, BitVector_Lexicompare(op1, op2) < 0);
+           } else
+               acc->val.ul = acc->val.ul < operand->val.ul;
+           break;
+       case EXPR_GT:
+           if (result) {
+               BitVector_Empty(result);
+               BitVector_LSB(result, BitVector_Lexicompare(op1, op2) > 0);
+           } else
+               acc->val.ul = acc->val.ul > operand->val.ul;
+           break;
+       case EXPR_LE:
+           if (result) {
+               BitVector_Empty(result);
+               BitVector_LSB(result, BitVector_Lexicompare(op1, op2) <= 0);
+           } else
+               acc->val.ul = acc->val.ul <= operand->val.ul;
+           break;
+       case EXPR_GE:
+           if (result) {
+               BitVector_Empty(result);
+               BitVector_LSB(result, BitVector_Lexicompare(op1, op2) >= 0);
+           } else
+               acc->val.ul = acc->val.ul >= operand->val.ul;
+           break;
+       case EXPR_NE:
+           if (result) {
+               BitVector_Empty(result);
+               BitVector_LSB(result, !BitVector_equal(op1, op2));
+           } else
+               acc->val.ul = acc->val.ul != operand->val.ul;
+           break;
+       case EXPR_IDENT:
+           if (result)
+               BitVector_Copy(result, op1);
+           break;
+    }
+
+    /* If we were doing a bitvector computation... */
+    if (result) {
+       BitVector_Destroy(spare);
+
+       if (op1 && acc->type != INTNUM_BV)
+           BitVector_Destroy(op1);
+       if (op2 && operand && operand->type != INTNUM_BV)
+           BitVector_Destroy(op2);
+
+       /* Try to fit the result into 32 bits if possible */
+       if (Set_Max(result) < 32) {
+           if (acc->type == INTNUM_BV) {
+               BitVector_Destroy(acc->val.bv);
+               acc->type = INTNUM_UL;
+           }
+           acc->val.ul = BitVector_Chunk_Read(result, 32, 0);
+           BitVector_Destroy(result);
+       } else {
+           if (acc->type == INTNUM_BV) {
+               BitVector_Copy(acc->val.bv, result);
+               BitVector_Destroy(result);
+           } else {
+               acc->type = INTNUM_BV;
+               acc->val.bv = result;
+           }
+       }
+    }
+}
+
+int
+intnum_is_zero(intnum *intn)
+{
+    return ((intn->type == INTNUM_UL && intn->val.ul == 0) ||
+           (intn->type == INTNUM_BV && BitVector_is_empty(intn->val.bv)));
+}
+
+int
+intnum_is_pos1(intnum *intn)
+{
+    return ((intn->type == INTNUM_UL && intn->val.ul == 1) ||
+           (intn->type == INTNUM_BV && Set_Max(intn->val.bv) == 0));
+}
+
+int
+intnum_is_neg1(intnum *intn)
+{
+    return ((intn->type == INTNUM_UL && intn->val.ul == -1) ||
+           (intn->type == INTNUM_BV && BitVector_is_full(intn->val.bv)));
+}
+
+void
+intnum_get_int(unsigned long *ret_val, const intnum *intn)
+{
+    switch (intn->type) {
+       case INTNUM_UL:
+           *ret_val = intn->val.ul;
+           break;
+       case INTNUM_BV:
+           *ret_val = BitVector_Chunk_Read(intn->val.bv, 32, 0);
+           break;
+    }
+}
+
+void
+intnum_get_sized(unsigned char *ptr, const intnum *intn, size_t size)
+{
+    unsigned long ul;
+    unsigned char *buf;
+    unsigned int len;
+
+    switch (intn->type) {
+       case INTNUM_UL:
+           ul = intn->val.ul;
+           while (size-- > 0) {
+               WRITE_BYTE(ptr, ul);
+               if (ul != 0)
+                   ul >>= 8;
+           }
+           break;
+       case INTNUM_BV:
+           buf = BitVector_Block_Read(intn->val.bv, &len);
+           if (len < size)
+               InternalError(__LINE__, __FILE__,
+                             _("Invalid size specified (too large)"));
+           memcpy(ptr, buf, size);
+           free(buf);
+           break;
+    }
+}
+
+/* Return 1 if okay size, 0 if not */
+int
+intnum_check_size(const intnum *intn, size_t size)
+{
+    switch (intn->type) {
+       case INTNUM_UL:
+           if (size >= 4)
+               return 1;
+           switch (size) {
+               case 3:
+                   return ((intn->val.ul & 0x00FFFFFF) == intn->val.ul);
+               case 2:
+                   return ((intn->val.ul & 0x0000FFFF) == intn->val.ul);
+               case 1:
+                   return ((intn->val.ul & 0x000000FF) == intn->val.ul);
+           }
+           break;
+       case INTNUM_BV:
+           if (size >= 10)
+               return 1;
+           else
+               return (Set_Max(intn->val.bv) < size*8);
+           break;
+    }
+    return 0;
+}
+
+void
+intnum_print(const intnum *intn)
+{
+    unsigned char *s;
+
+    switch (intn->type) {
+       case INTNUM_UL:
+           printf("0x%lx/%u", intn->val.ul, (unsigned int)intn->origsize);
+           break;
+       case INTNUM_BV:
+           s = BitVector_to_Hex(intn->val.bv);
+           printf("0x%s/%u", s, (unsigned int)intn->origsize);
+           free(s);
+           break;
+    }
+}
diff --git a/libyasm/intnum.h b/libyasm/intnum.h
new file mode 100644 (file)
index 0000000..62fe9e2
--- /dev/null
@@ -0,0 +1,96 @@
+/* $IdPath$
+ * Integer number functions header file.
+ *
+ *  Copyright (C) 2001  Peter Johnson
+ *
+ *  This file is part of YASM.
+ *
+ *  YASM is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  YASM is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#ifndef YASM_INTNUM_H
+#define YASM_INTNUM_H
+
+#ifndef YASM_EXPROP
+#define YASM_EXPROP
+typedef enum {
+    EXPR_ADD,
+    EXPR_SUB,
+    EXPR_MUL,
+    EXPR_DIV,
+    EXPR_SIGNDIV,
+    EXPR_MOD,
+    EXPR_SIGNMOD,
+    EXPR_NEG,
+    EXPR_NOT,
+    EXPR_OR,
+    EXPR_AND,
+    EXPR_XOR,
+    EXPR_SHL,
+    EXPR_SHR,
+    EXPR_LOR,
+    EXPR_LAND,
+    EXPR_LNOT,
+    EXPR_LT,
+    EXPR_GT,
+    EXPR_EQ,
+    EXPR_LE,
+    EXPR_GE,
+    EXPR_NE,
+    EXPR_IDENT /* if right is IDENT, then the entire expr is just a num */
+} ExprOp;
+#endif
+
+#ifndef YASM_INTNUM
+#define YASM_INTNUM
+typedef struct intnum intnum;
+#endif
+
+intnum *intnum_new_dec(char *str);
+intnum *intnum_new_bin(char *str);
+intnum *intnum_new_oct(char *str);
+intnum *intnum_new_hex(char *str);
+/* convert character constant to integer value, using NASM rules */
+intnum *intnum_new_charconst_nasm(const char *str);
+intnum *intnum_new_int(unsigned long i);
+void intnum_delete(intnum *intn);
+
+/* calculation function: acc = acc op operand */
+void intnum_calc(intnum *acc, ExprOp op, intnum *operand);
+
+/* simple value checks (for catching identities and the like) */
+int intnum_is_zero(intnum *acc);
+int intnum_is_pos1(intnum *acc);
+int intnum_is_neg1(intnum *acc);
+
+/* The get functions truncate intn to the size specified; they don't check
+ * for overflow.  Use intnum_check_size() to check for overflow.
+ */
+
+/* Return a 32-bit value in "standard" C format (eg, of unknown endian). */
+void intnum_get_int(unsigned long *ret_val, const intnum *intn);
+
+/* ptr will point to the Intel-format little-endian byte string after
+ * call (eg, [0] should be the first byte output to the file).
+ */
+void intnum_get_sized(unsigned char *ptr, const intnum *intn, size_t size);
+
+/* Check to see if intn will fit without overflow in size bytes.
+ * Returns 1 if it will, 0 if not.
+ */
+int intnum_check_size(const intnum *intn, size_t size);
+
+void intnum_print(const intnum *intn);
+
+#endif
index e655a5c2ec518ccdf2fda24f27ddc07f11313468..d9db4be3f6c13c04614840a2728e704a06964f9f 100644 (file)
@@ -124,8 +124,42 @@ sections_switch(sectionhead *headp, objfmt *of, const char *name)
     return s;
 }
 
+void
+sections_print(sectionhead *headp)
+{
+    section *cur;
+    
+    STAILQ_FOREACH(cur, headp, link)
+       section_print(cur);
+}
+
 bytecodehead *
 section_get_bytecodes(section *sect)
 {
     return &sect->bc;
 }
+
+const char *
+section_get_name(const section *sect)
+{
+    return sect->name;
+}
+
+void
+section_print(const section *sect)
+{
+    printf("***SECTION %s***\n", sect->name);
+    printf(" type=");
+    switch (sect->type) {
+       case SECTION_GENERAL:
+           printf("general\n");
+           break;
+       case SECTION_ABSOLUTE:
+           printf("absolute\n");
+           printf("start=%lu\n", sect->data.start);
+           break;
+    }
+
+    printf(" Bytecodes:\n");
+    bytecodes_print(&sect->bc);
+}
index ff881721cacf0b115cc488415ea0658672bccecf..93aa3de4bf5e8824fe4bbdc355d4a124ee90eda8 100644 (file)
@@ -36,5 +36,11 @@ section *sections_initialize(sectionhead *headp, struct objfmt_s *of);
 section *sections_switch(sectionhead *headp, struct objfmt_s *of,
                         const char *name);
 
+void sections_print(sectionhead *headp);
+
 bytecodehead *section_get_bytecodes(section *sect);
+
+const char *section_get_name(const section *sect);
+
+void section_print(const section *sect);
 #endif
index 639d37e2c21aa4c17ad2b05b77888d176f7d51aa..d18f352e93eb2c6cdd3ba3c46abee3b15c04c551 100644 (file)
@@ -25,6 +25,8 @@
 
 #include "util.h"
 
+#include <stdio.h>
+
 #ifdef STDC_HEADERS
 # include <stdlib.h>
 # include <string.h>
@@ -36,6 +38,7 @@
 #include "globals.h"
 #include "errwarn.h"
 #include "floatnum.h"
+#include "expr.h"
 #include "symrec.h"
 
 #include "bytecode.h"
@@ -48,13 +51,13 @@ typedef enum {
     SYM_NOSTATUS = 0,
     SYM_USED = 1 << 0,         /* for using variables before definition */
     SYM_DEFINED = 1 << 1,      /* once it's been defined in the file */
-    SYM_VALUED = 1 << 2                /* once its value has been determined */
+    SYM_VALUED = 1 << 2,       /* once its value has been determined */
+    SYM_NOTINTABLE = 1 << 3    /* if it's not in sym_table (ex. '$') */
 } SymStatus;
 
 typedef enum {
     SYM_UNKNOWN,               /* for unknown type (COMMON/EXTERN) */
-    SYM_CONSTANT_INT,          /* for EQU defined symbols (integers) */
-    SYM_CONSTANT_FLOAT,                /*  (floating point) */
+    SYM_EQU,                   /* for EQU defined symbols (expressions) */
     SYM_LABEL                  /* for labels */
 } SymType;
 
@@ -66,8 +69,7 @@ struct symrec {
     char *filename;            /* file and line */
     unsigned long line;                /*  symbol was first declared or used on */
     union {
-       unsigned long int_val;  /* integer constant */
-       floatnum *flt;          /* floating point constant */
+       expr *expn;             /* equ value */
        struct label_s {        /* bytecode immediately preceding a label */
            section *sect;
            bytecode *bc;
@@ -76,56 +78,60 @@ struct symrec {
 };
 
 /* private functions */
-static symrec *symrec_get_or_new(const char *);
-static symrec *symrec_define(const char *, SymType type);
+static symrec *symrec_get_or_new(const char *name, int in_table);
+static symrec *symrec_define(const char *name, SymType type, int in_table);
 
 /* The symbol table: a ternary tree. */
 static ternary_tree sym_table = (ternary_tree)NULL;
 
 /* create a new symrec */
 static symrec *
-symrec_get_or_new(const char *name)
+symrec_get_or_new(const char *name, int in_table)
 {
     symrec *rec, *rec2;
 
     rec = xmalloc(sizeof(symrec));
-    rec2 = ternary_insert(&sym_table, name, rec, 0);
+    if (in_table) {
+       rec2 = ternary_insert(&sym_table, name, rec, 0);
 
-    if (rec2 != rec) {
-       free(rec);
-       return rec2;
-    }
+       if (rec2 != rec) {
+           free(rec);
+           return rec2;
+       }
+       rec->status = SYM_NOSTATUS;
+    } else
+       rec->status = SYM_NOTINTABLE;
 
     rec->name = xstrdup(name);
     rec->type = SYM_UNKNOWN;
     rec->filename = xstrdup(in_filename);
     rec->line = line_number;
-    rec->status = SYM_NOSTATUS;
     rec->visibility = SYM_LOCAL;
 
     return rec;
 }
 
-/* call a function with each symrec.  stop early if 0 returned */
-void
-symrec_foreach(int (*func) (const char *name, symrec *rec))
+/* Call a function with each symrec.  Stops early if 0 returned by func.
+   Returns 0 if stopped early. */
+int
+symrec_foreach(int (*func) (symrec *sym))
 {
-    /* TODO */
+    return ternary_traverse(sym_table, (int (*) (void *))func);
 }
 
 symrec *
 symrec_use(const char *name)
 {
-    symrec *rec = symrec_get_or_new(name);
+    symrec *rec = symrec_get_or_new(name, 1);
 
     rec->status |= SYM_USED;
     return rec;
 }
 
 static symrec *
-symrec_define(const char *name, SymType type)
+symrec_define(const char *name, SymType type, int in_table)
 {
-    symrec *rec = symrec_get_or_new(name);
+    symrec *rec = symrec_get_or_new(name, in_table);
 
     /* Has it been defined before (either by DEFINED or COMMON/EXTERN)? */
     if (rec->status & SYM_DEFINED) {
@@ -140,27 +146,19 @@ symrec_define(const char *name, SymType type)
 }
 
 symrec *
-symrec_define_constant_int(const char *name, unsigned long int_val)
+symrec_define_equ(const char *name, expr *e)
 {
-    symrec *rec = symrec_define(name, SYM_CONSTANT_INT);
-    rec->value.int_val = int_val;
+    symrec *rec = symrec_define(name, SYM_EQU, 1);
+    rec->value.expn = e;
     rec->status |= SYM_VALUED;
     return rec;
 }
 
 symrec *
-symrec_define_constant_float(const char *name, floatnum *flt)
+symrec_define_label(const char *name, section *sect, bytecode *precbc,
+                   int in_table)
 {
-    symrec *rec = symrec_define(name, SYM_CONSTANT_FLOAT);
-    rec->value.flt = flt;
-    rec->status |= SYM_VALUED;
-    return rec;
-}
-
-symrec *
-symrec_define_label(const char *name, section *sect, bytecode *precbc)
-{
-    symrec *rec = symrec_define(name, SYM_LABEL);
+    symrec *rec = symrec_define(name, SYM_LABEL, in_table);
     rec->value.label.sect = sect;
     rec->value.label.bc = precbc;
     return rec;
@@ -169,7 +167,7 @@ symrec_define_label(const char *name, section *sect, bytecode *precbc)
 symrec *
 symrec_declare(const char *name, SymVisibility vis)
 {
-    symrec *rec = symrec_get_or_new(name);
+    symrec *rec = symrec_get_or_new(name, 1);
 
     /* Don't allow EXTERN and COMMON if symbol has already been DEFINED. */
     /* Also, EXTERN and COMMON are mutually exclusive. */
@@ -188,7 +186,7 @@ symrec_declare(const char *name, SymVisibility vis)
     }
     return rec;
 }
-
+#if 0
 int
 symrec_get_int_value(const symrec *sym, unsigned long *ret_val,
                     int resolve_label)
@@ -224,9 +222,67 @@ symrec_get_int_value(const symrec *sym, unsigned long *ret_val,
     /* We can't get the value right now. */
     return 0;
 }
-
+#endif
 const char *
 symrec_get_name(const symrec *sym)
 {
     return sym->name;
 }
+
+void
+symrec_print(const symrec *sym)
+{
+    printf("---Symbol `%s'---\n", sym->name);
+
+    switch (sym->type) {
+       case SYM_UNKNOWN:
+           printf("-Unknown (Common/Extern)-\n");
+           break;
+       case SYM_EQU:
+           printf("_EQU_\n");
+           printf("Expn=");
+           expr_print(sym->value.expn);
+           printf("\n");
+           break;
+       case SYM_LABEL:
+           printf("_Label_\n");
+           printf("Section=`%s'\n", section_get_name(sym->value.label.sect));
+           if (!sym->value.label.bc)
+               printf("[First bytecode]\n");
+           else {
+               printf("[Preceding bytecode]\n");
+               bytecode_print(sym->value.label.bc);
+           }
+           break;
+    }
+
+    printf("Status=");
+    if (sym->status == SYM_NOSTATUS)
+       printf("None\n");
+    else {
+       if (sym->status & SYM_USED)
+           printf("Used,");
+       if (sym->status & SYM_DEFINED)
+           printf("Defined,");
+       if (sym->status & SYM_VALUED)
+           printf("Valued,");
+       if (sym->status & SYM_NOTINTABLE)
+           printf("Not in Table,");
+       printf("\n");
+    }
+
+    printf("Visibility=");
+    if (sym->visibility == SYM_LOCAL)
+       printf("Local\n");
+    else {
+       if (sym->visibility & SYM_GLOBAL)
+           printf("Global,");
+       if (sym->visibility & SYM_COMMON)
+           printf("Common,");
+       if (sym->visibility & SYM_EXTERN)
+           printf("Extern,");
+       printf("\n");
+    }
+
+    printf("Filename=\"%s\" Line Number=%lu\n", sym->filename, sym->line);
+}
index 3b4cd8c3f73ba00756727a68d9d24db4f235a060..2f136021e5f7ed1aadb744b1cc3f67a71880c878 100644 (file)
@@ -22,9 +22,9 @@
 #ifndef YASM_SYMREC_H
 #define YASM_SYMREC_H
 
-#ifndef YASM_FLOATNUM
-#define YASM_FLOATNUM
-typedef struct floatnum floatnum;
+#ifndef YASM_EXPR
+#define YASM_EXPR
+typedef struct expr expr;
 #endif
 
 #ifndef YASM_SECTION
@@ -51,9 +51,10 @@ typedef struct symrec symrec;
 #endif
 
 symrec *symrec_use(const char *name);
-symrec *symrec_define_constant_int(const char *name, unsigned long int_val);
-symrec *symrec_define_constant_float(const char *name, floatnum *flt);
-symrec *symrec_define_label(const char *name, section *sect, bytecode *precbc);
+symrec *symrec_define_equ(const char *name, expr *e);
+/* in_table specifies if the label should be inserted into the symbol table. */
+symrec *symrec_define_label(const char *name, section *sect, bytecode *precbc,
+                           int in_table);
 symrec *symrec_declare(const char *name, SymVisibility vis);
 
 /* Get the numeric 32-bit value of a symbol if possible.
@@ -66,6 +67,7 @@ int symrec_get_int_value(const symrec *sym, unsigned long *ret_val,
 
 const char *symrec_get_name(const symrec *sym);
 
-void symrec_foreach(int (*func) (const char *name, symrec *rec));
+int symrec_foreach(int (*func) (symrec *sym));
 
+void symrec_print(const symrec *sym);
 #endif
index d768e3c7adf1a8235cf213d4cc6a03514da679a7..78ef88e8b3e86922861aa5227f1cdb42262d16e6 100644 (file)
@@ -287,7 +287,8 @@ START_TEST(test_get_single_normalized)
 
     for (i=0; i<num; i++) {
        get_common_setup(vals, i);
-       fail_unless(floatnum_get_single(outval, flt) == vals[i].ret32, ret_msg);
+       fail_unless(floatnum_get_sized(outval, flt, 4) == vals[i].ret32,
+                   ret_msg);
        fail_unless(get_common_check_result(4, outval, vals[i].result32) == 0,
                    result_msg);
     }
@@ -302,7 +303,8 @@ START_TEST(test_get_single_normalized_edgecase)
 
     for (i=0; i<num; i++) {
        get_common_setup(vals, i);
-       fail_unless(floatnum_get_single(outval, flt) == vals[i].ret32, ret_msg);
+       fail_unless(floatnum_get_sized(outval, flt, 4) == vals[i].ret32,
+                   ret_msg);
        fail_unless(get_common_check_result(4, outval, vals[i].result32) == 0,
                    result_msg);
     }
@@ -321,7 +323,8 @@ START_TEST(test_get_double_normalized)
 
     for (i=0; i<num; i++) {
        get_common_setup(vals, i);
-       fail_unless(floatnum_get_double(outval, flt) == vals[i].ret64, ret_msg);
+       fail_unless(floatnum_get_sized(outval, flt, 8) == vals[i].ret64,
+                   ret_msg);
        fail_unless(get_common_check_result(8, outval, vals[i].result64) == 0,
                    result_msg);
     }
@@ -336,7 +339,8 @@ START_TEST(test_get_double_normalized_edgecase)
 
     for (i=0; i<num; i++) {
        get_common_setup(vals, i);
-       fail_unless(floatnum_get_double(outval, flt) == vals[i].ret64, ret_msg);
+       fail_unless(floatnum_get_sized(outval, flt, 8) == vals[i].ret64,
+                   ret_msg);
        fail_unless(get_common_check_result(8, outval, vals[i].result64) == 0,
                    result_msg);
     }
@@ -355,7 +359,7 @@ START_TEST(test_get_extended_normalized)
 
     for (i=0; i<num; i++) {
        get_common_setup(vals, i);
-       fail_unless(floatnum_get_extended(outval, flt) == vals[i].ret80,
+       fail_unless(floatnum_get_sized(outval, flt, 10) == vals[i].ret80,
                    ret_msg);
        fail_unless(get_common_check_result(10, outval, vals[i].result80) == 0,
                    result_msg);
@@ -371,7 +375,7 @@ START_TEST(test_get_extended_normalized_edgecase)
 
     for (i=0; i<num; i++) {
        get_common_setup(vals, i);
-       fail_unless(floatnum_get_extended(outval, flt) == vals[i].ret80,
+       fail_unless(floatnum_get_sized(outval, flt, 10) == vals[i].ret80,
                    ret_msg);
        fail_unless(get_common_check_result(10, outval, vals[i].result80) == 0,
                    result_msg);
index 558715f9de49f7315e72a27d31d5a2eed8b2a234..670275c673b7fe924f16e7bb8c5a43987db05cf8 100644 (file)
@@ -33,10 +33,6 @@ char *xstrdup(const char *str);
 char *strsep(char **stringp, const char *delim);
 #endif
 
-#if !defined(HAVE_STRTOUL) || defined(HAVE_GNU_C_LIBRARY)
-unsigned long strtoul(const char *nptr, char **endptr, int base);
-#endif
-
 #ifndef HAVE_STRCASECMP
 # ifdef HAVE_STRICMP
 #  define strcasecmp(x, y)     stricmp(x, y)
index 911fe47dd75f1ae4e494f5cac1889ad456a607d5..252065f738b874426ff4d93aa996c0a79ef8b433 100644 (file)
 #define N_(String)     (String)
 #endif
 
+#include "bitvect.h"
+
 #include "globals.h"
 #include "errwarn.h"
+#include "intnum.h"
 #include "floatnum.h"
 #include "expr.h"
 #include "symrec.h"
@@ -61,7 +64,7 @@ struct ExprItem {
     union {
        symrec *sym;
        expr *expn;
-       unsigned long int_val;
+       intnum *intn;
        floatnum *flt;
     } data;
 };
@@ -69,6 +72,8 @@ struct ExprItem {
 struct expr {
     ExprItem left, right;
     ExprOp op;
+    char *filename;
+    unsigned long line;
 };
 
 /* allocate a new expression node, with children as defined.
@@ -93,6 +98,10 @@ expr_new(ExprItem *left, ExprOp op, ExprItem *right)
        InternalError(__LINE__, __FILE__,
                      _("Right side of expression must exist"));
     }
+
+    ptr->filename = xstrdup(in_filename);
+    ptr->line = line_number;
+
     return ptr;
 }
 
@@ -116,11 +125,11 @@ ExprExpr(expr *x)
 }
 
 ExprItem *
-ExprInt(unsigned long i)
+ExprInt(intnum *i)
 {
     ExprItem *e = xmalloc(sizeof(ExprItem));
     e->type = EXPR_INT;
-    e->data.int_val = i;
+    e->data.intn = i;
     return e;
 }
 
@@ -138,7 +147,7 @@ int
 expr_simplify(expr *e)
 {
     int simplified = 0;
-    unsigned long int_val;
+    ExprItem tmp;
 
     /* try to simplify the left side */
     if (e->left.type == EXPR_EXPR) {
@@ -150,14 +159,14 @@ expr_simplify(expr *e)
         * pull it up into the current node */
        while (e->left.type == EXPR_EXPR &&
               e->left.data.expn->op == EXPR_IDENT) {
-           ExprItem tmp;
-           e->left.type = e->left.data.expn->right.type;
            memcpy(&tmp, &(e->left.data.expn->right), sizeof(ExprItem));
            free(e->left.data.expn);
-           memcpy(&(e->left.data.int_val), &tmp, sizeof(ExprItem));
+           memcpy(&e->left, &tmp, sizeof(ExprItem));
            simplified = 1;
        }
-    } else if (e->left.type == EXPR_SYM) {
+    }
+#if 0
+    else if (e->left.type == EXPR_SYM) {
        /* try to get value of symbol */
        if (symrec_get_int_value(e->left.data.sym, &int_val, 0)) {
            e->left.type = EXPR_INT;
@@ -166,6 +175,7 @@ expr_simplify(expr *e)
            simplified = 1;
        }
     }
+#endif
 
     /* ditto on the right */
     if (e->right.type == EXPR_EXPR) {
@@ -174,14 +184,14 @@ expr_simplify(expr *e)
 
        while (e->right.type == EXPR_EXPR &&
               e->right.data.expn->op == EXPR_IDENT) {
-           ExprItem tmp;
-           e->right.type = e->right.data.expn->right.type;
            memcpy(&tmp, &(e->right.data.expn->right), sizeof(ExprItem));
            free(e->right.data.expn);
-           memcpy(&(e->right.data.int_val), &tmp, sizeof(ExprItem));
+           memcpy(&e->right, &tmp, sizeof(ExprItem));
            simplified = 1;
        }
-    } else if (e->right.type == EXPR_SYM) {
+    }
+#if 0
+    else if (e->right.type == EXPR_SYM) {
        if (symrec_get_int_value(e->right.data.sym, &int_val, 0)) {
            e->right.type = EXPR_INT;
            /* don't try to free the symrec here. */
@@ -189,139 +199,45 @@ expr_simplify(expr *e)
            simplified = 1;
        }
     }
-
-    if ((e->left.type == EXPR_INT || e->left.type == EXPR_NONE) &&
-       e->right.type == EXPR_INT && e->op != EXPR_IDENT) {
-       switch (e->op) {
-           case EXPR_ADD:
-               e->right.data.int_val = e->left.data.int_val +
-                                       e->right.data.int_val;
-               break;
-           case EXPR_SUB:
-               e->right.data.int_val = e->left.data.int_val -
-                                       e->right.data.int_val;
-               break;
-           case EXPR_MUL:
-               e->right.data.int_val = e->left.data.int_val *
-                                       e->right.data.int_val;
-               break;
-           case EXPR_DIV:
-               e->right.data.int_val = e->left.data.int_val /
-                                       e->right.data.int_val;
-               break;
-           case EXPR_MOD:
-               e->right.data.int_val = e->left.data.int_val %
-                                       e->right.data.int_val;
-               break;
-           case EXPR_NEG:
-               e->right.data.int_val = -(e->right.data.int_val);
-               break;
-           case EXPR_NOT:
-               e->right.data.int_val = ~(e->right.data.int_val);
-               break;
-           case EXPR_OR:
-               e->right.data.int_val = e->left.data.int_val |
-                                       e->right.data.int_val;
-               break;
-           case EXPR_AND:
-               e->right.data.int_val = e->left.data.int_val &
-                                       e->right.data.int_val;
-               break;
-           case EXPR_XOR:
-               e->right.data.int_val = e->left.data.int_val ^
-                                       e->right.data.int_val;
-               break;
-           case EXPR_SHL:
-               e->right.data.int_val = e->right.data.int_val <<
-                                       e->left.data.int_val;
-               break;
-           case EXPR_SHR:
-               e->right.data.int_val = e->right.data.int_val >>
-                                       e->left.data.int_val;
-               break;
-           case EXPR_LOR:
-               e->right.data.int_val = e->left.data.int_val ||
-                                       e->right.data.int_val;
-               break;
-           case EXPR_LAND:
-               e->right.data.int_val = e->left.data.int_val &&
-                                       e->right.data.int_val;
-               break;
-           case EXPR_LNOT:
-               e->right.data.int_val = !e->right.data.int_val;
-               break;
-           case EXPR_EQ:
-               e->right.data.int_val = e->right.data.int_val ==
-                                       e->left.data.int_val;
-               break;
-           case EXPR_LT:
-               e->right.data.int_val = e->right.data.int_val <
-                                       e->left.data.int_val;
-               break;
-           case EXPR_GT:
-               e->right.data.int_val = e->right.data.int_val >
-                                       e->left.data.int_val;
-               break;
-           case EXPR_LE:
-               e->right.data.int_val = e->right.data.int_val <=
-                                       e->left.data.int_val;
-               break;
-           case EXPR_GE:
-               e->right.data.int_val = e->right.data.int_val >=
-                                       e->left.data.int_val;
-               break;
-           case EXPR_NE:
-               e->right.data.int_val = e->right.data.int_val !=
-                                       e->left.data.int_val;
-               break;
-           case EXPR_IDENT:
-               break;
-       }
-       e->op = EXPR_IDENT;
-       simplified = 1;
-    }
+#endif
 
     /* catch simple identities like 0+x, 1*x, etc., for x not a num */
-    else if (e->left.type == EXPR_INT &&
-            ((e->left.data.int_val == 1 && e->op == EXPR_MUL) ||
-             (e->left.data.int_val == 0 && e->op == EXPR_ADD) ||
-             (e->left.data.int_val == -1 && e->op == EXPR_AND) ||
-             (e->left.data.int_val == 0 && e->op == EXPR_OR))) {
+    if (e->left.type == EXPR_INT &&
+            ((intnum_is_pos1(e->left.data.intn) && e->op == EXPR_MUL) ||
+             (intnum_is_zero(e->left.data.intn) && e->op == EXPR_ADD) ||
+             (intnum_is_neg1(e->left.data.intn) && e->op == EXPR_AND) ||
+             (intnum_is_zero(e->left.data.intn) && e->op == EXPR_OR))) {
+       intnum_delete(e->left.data.intn);
        e->op = EXPR_IDENT;
        simplified = 1;
     }
     /* and the corresponding x+|-0, x*&/1 */
     else if (e->right.type == EXPR_INT &&
-            ((e->right.data.int_val == 1 && e->op == EXPR_MUL) ||
-             (e->right.data.int_val == 1 && e->op == EXPR_DIV) ||
-             (e->right.data.int_val == 0 && e->op == EXPR_ADD) ||
-             (e->right.data.int_val == 0 && e->op == EXPR_SUB) ||
-             (e->right.data.int_val == -1 && e->op == EXPR_AND) ||
-             (e->right.data.int_val == 0 && e->op == EXPR_OR) ||
-             (e->right.data.int_val == 0 && e->op == EXPR_SHL) ||
-             (e->right.data.int_val == 0 && e->op == EXPR_SHR))) {
+            ((intnum_is_pos1(e->right.data.intn) && e->op == EXPR_MUL) ||
+             (intnum_is_pos1(e->right.data.intn) && e->op == EXPR_DIV) ||
+             (intnum_is_zero(e->right.data.intn) && e->op == EXPR_ADD) ||
+             (intnum_is_zero(e->right.data.intn) && e->op == EXPR_SUB) ||
+             (intnum_is_neg1(e->right.data.intn) && e->op == EXPR_AND) ||
+             (intnum_is_zero(e->right.data.intn) && e->op == EXPR_OR) ||
+             (intnum_is_zero(e->right.data.intn) && e->op == EXPR_SHL) ||
+             (intnum_is_zero(e->right.data.intn) && e->op == EXPR_SHR))) {
+       intnum_delete(e->right.data.intn);
        e->op = EXPR_IDENT;
        e->right.type = e->left.type;
        memcpy(&e->right, &e->left, sizeof(ExprItem));
        simplified = 1;
+    } else if ((e->left.type == EXPR_INT || e->left.type == EXPR_NONE) &&
+       e->right.type == EXPR_INT && e->op != EXPR_IDENT) {
+       intnum_calc(e->left.data.intn, e->op, e->right.data.intn);
+       intnum_delete(e->right.data.intn);
+       e->right.data.intn = e->left.data.intn;
+       e->op = EXPR_IDENT;
+       simplified = 1;
     }
 
     return simplified;
 }
 
-int
-expr_get_value(expr *e, unsigned long *retval)
-{
-    while (!(e->op == EXPR_IDENT && e->right.type == EXPR_INT)
-          && expr_simplify(e)) ;
-
-    if (e->op == EXPR_IDENT && e->right.type == EXPR_INT) {
-       *retval = e->right.data.int_val;
-       return 1;
-    } else
-       return 0;
-}
-
 void
 expr_print(expr *e)
 {
@@ -336,7 +252,7 @@ expr_print(expr *e)
                printf(")");
                break;
            case EXPR_INT:
-               printf("%lu", e->left.data.int_val);
+               intnum_print(e->left.data.intn);
                break;
            case EXPR_FLOAT:
                floatnum_print(e->left.data.flt);
@@ -358,9 +274,15 @@ expr_print(expr *e)
        case EXPR_DIV:
            printf("/");
            break;
+       case EXPR_SIGNDIV:
+           printf("//");
+           break;
        case EXPR_MOD:
            printf("%%");
            break;
+       case EXPR_SIGNMOD:
+           printf("%%%%");
+           break;
        case EXPR_NEG:
            printf("-");
            break;
@@ -422,7 +344,7 @@ expr_print(expr *e)
            printf(")");
            break;
        case EXPR_INT:
-           printf("%lu", e->right.data.int_val);
+           intnum_print(e->right.data.intn);
            break;
        case EXPR_FLOAT:
            floatnum_print(e->right.data.flt);
index 911fe47dd75f1ae4e494f5cac1889ad456a607d5..252065f738b874426ff4d93aa996c0a79ef8b433 100644 (file)
 #define N_(String)     (String)
 #endif
 
+#include "bitvect.h"
+
 #include "globals.h"
 #include "errwarn.h"
+#include "intnum.h"
 #include "floatnum.h"
 #include "expr.h"
 #include "symrec.h"
@@ -61,7 +64,7 @@ struct ExprItem {
     union {
        symrec *sym;
        expr *expn;
-       unsigned long int_val;
+       intnum *intn;
        floatnum *flt;
     } data;
 };
@@ -69,6 +72,8 @@ struct ExprItem {
 struct expr {
     ExprItem left, right;
     ExprOp op;
+    char *filename;
+    unsigned long line;
 };
 
 /* allocate a new expression node, with children as defined.
@@ -93,6 +98,10 @@ expr_new(ExprItem *left, ExprOp op, ExprItem *right)
        InternalError(__LINE__, __FILE__,
                      _("Right side of expression must exist"));
     }
+
+    ptr->filename = xstrdup(in_filename);
+    ptr->line = line_number;
+
     return ptr;
 }
 
@@ -116,11 +125,11 @@ ExprExpr(expr *x)
 }
 
 ExprItem *
-ExprInt(unsigned long i)
+ExprInt(intnum *i)
 {
     ExprItem *e = xmalloc(sizeof(ExprItem));
     e->type = EXPR_INT;
-    e->data.int_val = i;
+    e->data.intn = i;
     return e;
 }
 
@@ -138,7 +147,7 @@ int
 expr_simplify(expr *e)
 {
     int simplified = 0;
-    unsigned long int_val;
+    ExprItem tmp;
 
     /* try to simplify the left side */
     if (e->left.type == EXPR_EXPR) {
@@ -150,14 +159,14 @@ expr_simplify(expr *e)
         * pull it up into the current node */
        while (e->left.type == EXPR_EXPR &&
               e->left.data.expn->op == EXPR_IDENT) {
-           ExprItem tmp;
-           e->left.type = e->left.data.expn->right.type;
            memcpy(&tmp, &(e->left.data.expn->right), sizeof(ExprItem));
            free(e->left.data.expn);
-           memcpy(&(e->left.data.int_val), &tmp, sizeof(ExprItem));
+           memcpy(&e->left, &tmp, sizeof(ExprItem));
            simplified = 1;
        }
-    } else if (e->left.type == EXPR_SYM) {
+    }
+#if 0
+    else if (e->left.type == EXPR_SYM) {
        /* try to get value of symbol */
        if (symrec_get_int_value(e->left.data.sym, &int_val, 0)) {
            e->left.type = EXPR_INT;
@@ -166,6 +175,7 @@ expr_simplify(expr *e)
            simplified = 1;
        }
     }
+#endif
 
     /* ditto on the right */
     if (e->right.type == EXPR_EXPR) {
@@ -174,14 +184,14 @@ expr_simplify(expr *e)
 
        while (e->right.type == EXPR_EXPR &&
               e->right.data.expn->op == EXPR_IDENT) {
-           ExprItem tmp;
-           e->right.type = e->right.data.expn->right.type;
            memcpy(&tmp, &(e->right.data.expn->right), sizeof(ExprItem));
            free(e->right.data.expn);
-           memcpy(&(e->right.data.int_val), &tmp, sizeof(ExprItem));
+           memcpy(&e->right, &tmp, sizeof(ExprItem));
            simplified = 1;
        }
-    } else if (e->right.type == EXPR_SYM) {
+    }
+#if 0
+    else if (e->right.type == EXPR_SYM) {
        if (symrec_get_int_value(e->right.data.sym, &int_val, 0)) {
            e->right.type = EXPR_INT;
            /* don't try to free the symrec here. */
@@ -189,139 +199,45 @@ expr_simplify(expr *e)
            simplified = 1;
        }
     }
-
-    if ((e->left.type == EXPR_INT || e->left.type == EXPR_NONE) &&
-       e->right.type == EXPR_INT && e->op != EXPR_IDENT) {
-       switch (e->op) {
-           case EXPR_ADD:
-               e->right.data.int_val = e->left.data.int_val +
-                                       e->right.data.int_val;
-               break;
-           case EXPR_SUB:
-               e->right.data.int_val = e->left.data.int_val -
-                                       e->right.data.int_val;
-               break;
-           case EXPR_MUL:
-               e->right.data.int_val = e->left.data.int_val *
-                                       e->right.data.int_val;
-               break;
-           case EXPR_DIV:
-               e->right.data.int_val = e->left.data.int_val /
-                                       e->right.data.int_val;
-               break;
-           case EXPR_MOD:
-               e->right.data.int_val = e->left.data.int_val %
-                                       e->right.data.int_val;
-               break;
-           case EXPR_NEG:
-               e->right.data.int_val = -(e->right.data.int_val);
-               break;
-           case EXPR_NOT:
-               e->right.data.int_val = ~(e->right.data.int_val);
-               break;
-           case EXPR_OR:
-               e->right.data.int_val = e->left.data.int_val |
-                                       e->right.data.int_val;
-               break;
-           case EXPR_AND:
-               e->right.data.int_val = e->left.data.int_val &
-                                       e->right.data.int_val;
-               break;
-           case EXPR_XOR:
-               e->right.data.int_val = e->left.data.int_val ^
-                                       e->right.data.int_val;
-               break;
-           case EXPR_SHL:
-               e->right.data.int_val = e->right.data.int_val <<
-                                       e->left.data.int_val;
-               break;
-           case EXPR_SHR:
-               e->right.data.int_val = e->right.data.int_val >>
-                                       e->left.data.int_val;
-               break;
-           case EXPR_LOR:
-               e->right.data.int_val = e->left.data.int_val ||
-                                       e->right.data.int_val;
-               break;
-           case EXPR_LAND:
-               e->right.data.int_val = e->left.data.int_val &&
-                                       e->right.data.int_val;
-               break;
-           case EXPR_LNOT:
-               e->right.data.int_val = !e->right.data.int_val;
-               break;
-           case EXPR_EQ:
-               e->right.data.int_val = e->right.data.int_val ==
-                                       e->left.data.int_val;
-               break;
-           case EXPR_LT:
-               e->right.data.int_val = e->right.data.int_val <
-                                       e->left.data.int_val;
-               break;
-           case EXPR_GT:
-               e->right.data.int_val = e->right.data.int_val >
-                                       e->left.data.int_val;
-               break;
-           case EXPR_LE:
-               e->right.data.int_val = e->right.data.int_val <=
-                                       e->left.data.int_val;
-               break;
-           case EXPR_GE:
-               e->right.data.int_val = e->right.data.int_val >=
-                                       e->left.data.int_val;
-               break;
-           case EXPR_NE:
-               e->right.data.int_val = e->right.data.int_val !=
-                                       e->left.data.int_val;
-               break;
-           case EXPR_IDENT:
-               break;
-       }
-       e->op = EXPR_IDENT;
-       simplified = 1;
-    }
+#endif
 
     /* catch simple identities like 0+x, 1*x, etc., for x not a num */
-    else if (e->left.type == EXPR_INT &&
-            ((e->left.data.int_val == 1 && e->op == EXPR_MUL) ||
-             (e->left.data.int_val == 0 && e->op == EXPR_ADD) ||
-             (e->left.data.int_val == -1 && e->op == EXPR_AND) ||
-             (e->left.data.int_val == 0 && e->op == EXPR_OR))) {
+    if (e->left.type == EXPR_INT &&
+            ((intnum_is_pos1(e->left.data.intn) && e->op == EXPR_MUL) ||
+             (intnum_is_zero(e->left.data.intn) && e->op == EXPR_ADD) ||
+             (intnum_is_neg1(e->left.data.intn) && e->op == EXPR_AND) ||
+             (intnum_is_zero(e->left.data.intn) && e->op == EXPR_OR))) {
+       intnum_delete(e->left.data.intn);
        e->op = EXPR_IDENT;
        simplified = 1;
     }
     /* and the corresponding x+|-0, x*&/1 */
     else if (e->right.type == EXPR_INT &&
-            ((e->right.data.int_val == 1 && e->op == EXPR_MUL) ||
-             (e->right.data.int_val == 1 && e->op == EXPR_DIV) ||
-             (e->right.data.int_val == 0 && e->op == EXPR_ADD) ||
-             (e->right.data.int_val == 0 && e->op == EXPR_SUB) ||
-             (e->right.data.int_val == -1 && e->op == EXPR_AND) ||
-             (e->right.data.int_val == 0 && e->op == EXPR_OR) ||
-             (e->right.data.int_val == 0 && e->op == EXPR_SHL) ||
-             (e->right.data.int_val == 0 && e->op == EXPR_SHR))) {
+            ((intnum_is_pos1(e->right.data.intn) && e->op == EXPR_MUL) ||
+             (intnum_is_pos1(e->right.data.intn) && e->op == EXPR_DIV) ||
+             (intnum_is_zero(e->right.data.intn) && e->op == EXPR_ADD) ||
+             (intnum_is_zero(e->right.data.intn) && e->op == EXPR_SUB) ||
+             (intnum_is_neg1(e->right.data.intn) && e->op == EXPR_AND) ||
+             (intnum_is_zero(e->right.data.intn) && e->op == EXPR_OR) ||
+             (intnum_is_zero(e->right.data.intn) && e->op == EXPR_SHL) ||
+             (intnum_is_zero(e->right.data.intn) && e->op == EXPR_SHR))) {
+       intnum_delete(e->right.data.intn);
        e->op = EXPR_IDENT;
        e->right.type = e->left.type;
        memcpy(&e->right, &e->left, sizeof(ExprItem));
        simplified = 1;
+    } else if ((e->left.type == EXPR_INT || e->left.type == EXPR_NONE) &&
+       e->right.type == EXPR_INT && e->op != EXPR_IDENT) {
+       intnum_calc(e->left.data.intn, e->op, e->right.data.intn);
+       intnum_delete(e->right.data.intn);
+       e->right.data.intn = e->left.data.intn;
+       e->op = EXPR_IDENT;
+       simplified = 1;
     }
 
     return simplified;
 }
 
-int
-expr_get_value(expr *e, unsigned long *retval)
-{
-    while (!(e->op == EXPR_IDENT && e->right.type == EXPR_INT)
-          && expr_simplify(e)) ;
-
-    if (e->op == EXPR_IDENT && e->right.type == EXPR_INT) {
-       *retval = e->right.data.int_val;
-       return 1;
-    } else
-       return 0;
-}
-
 void
 expr_print(expr *e)
 {
@@ -336,7 +252,7 @@ expr_print(expr *e)
                printf(")");
                break;
            case EXPR_INT:
-               printf("%lu", e->left.data.int_val);
+               intnum_print(e->left.data.intn);
                break;
            case EXPR_FLOAT:
                floatnum_print(e->left.data.flt);
@@ -358,9 +274,15 @@ expr_print(expr *e)
        case EXPR_DIV:
            printf("/");
            break;
+       case EXPR_SIGNDIV:
+           printf("//");
+           break;
        case EXPR_MOD:
            printf("%%");
            break;
+       case EXPR_SIGNMOD:
+           printf("%%%%");
+           break;
        case EXPR_NEG:
            printf("-");
            break;
@@ -422,7 +344,7 @@ expr_print(expr *e)
            printf(")");
            break;
        case EXPR_INT:
-           printf("%lu", e->right.data.int_val);
+           intnum_print(e->right.data.intn);
            break;
        case EXPR_FLOAT:
            floatnum_print(e->right.data.flt);
index c69c2e66ed7f236fe23eab7bfbc3062f0fbf8529..e44fcf456b57adf1390ff2a82ce62df8ff12afb9 100644 (file)
 #include <libintl.h>
 #define _(String)      gettext(String)
 
+#include "bitvect.h"
+
 #include "globals.h"
 #include "errwarn.h"
+#include "intnum.h"
 #include "floatnum.h"
 #include "expr.h"
 #include "symrec.h"
@@ -51,7 +54,6 @@ RCSID("$IdPath$");
 
 void init_table(void);
 extern int nasm_parser_lex(void);
-static unsigned long ConvertCharConstToInt(char *);
 void nasm_parser_error(const char *);
 
 extern objfmt *nasm_parser_objfmt;
@@ -65,9 +67,11 @@ static bytecode *nasm_parser_temp_bc;
 %}
 
 %union {
-    unsigned long int_val;
+    unsigned int int_info;
     char *str_val;
+    intnum *intn;
     floatnum *flt;
+    symrec *sym;
     unsigned char groupdata[4];
     effaddr *ea;
     expr *exp;
@@ -78,23 +82,24 @@ static bytecode *nasm_parser_temp_bc;
     bytecode *bc;
 }
 
-%token <int_val> INTNUM
+%token <intn> INTNUM
 %token <flt> FLTNUM
 %token <str_val> DIRECTIVE_NAME DIRECTIVE_VAL STRING
-%token <int_val> BYTE WORD DWORD QWORD TWORD DQWORD
-%token <int_val> DECLARE_DATA
-%token <int_val> RESERVE_SPACE
+%token <int_info> BYTE WORD DWORD QWORD TWORD DQWORD
+%token <int_info> DECLARE_DATA
+%token <int_info> RESERVE_SPACE
 %token INCBIN EQU TIMES
 %token SEG WRT NEAR SHORT FAR NOSPLIT ORG
 %token TO
 %token O16 O32 A16 A32 LOCK REPNZ REP REPZ
-%token <int_val> OPERSIZE ADDRSIZE
-%token <int_val> CR4 CRREG_NOTCR4 DRREG TRREG ST0 FPUREG_NOTST0 MMXREG XMMREG
-%token <int_val> REG_EAX REG_ECX REG_EDX REG_EBX REG_ESP REG_EBP REG_ESI REG_EDI
-%token <int_val> REG_AX REG_CX REG_DX REG_BX REG_SP REG_BP REG_SI REG_DI
-%token <int_val> REG_AL REG_CL REG_DL REG_BL REG_AH REG_CH REG_DH REG_BH
-%token <int_val> REG_ES REG_CS REG_SS REG_DS REG_FS REG_GS
-%token LEFT_OP RIGHT_OP SIGNDIV SIGNMOD
+%token <int_info> OPERSIZE ADDRSIZE
+%token <int_info> CR4 CRREG_NOTCR4 DRREG TRREG ST0 FPUREG_NOTST0 MMXREG XMMREG
+%token <int_info> REG_EAX REG_ECX REG_EDX REG_EBX
+%token <int_info> REG_ESP REG_EBP REG_ESI REG_EDI
+%token <int_info> REG_AX REG_CX REG_DX REG_BX REG_SP REG_BP REG_SI REG_DI
+%token <int_info> REG_AL REG_CL REG_DL REG_BL REG_AH REG_CH REG_DH REG_BH
+%token <int_info> REG_ES REG_CS REG_SS REG_DS REG_FS REG_GS
+%token LEFT_OP RIGHT_OP SIGNDIV SIGNMOD START_SECTION_ID
 %token <str_val> ID LOCAL_ID SPECIAL_ID
 
 /* instruction tokens (dynamically generated) */
@@ -102,9 +107,9 @@ static bytecode *nasm_parser_temp_bc;
 
 /* @TYPES@ */
 
-%type <bc> line exp instr instrbase label
+%type <bc> line exp instr instrbase
 
-%type <int_val> fpureg reg32 reg16 reg8 segreg
+%type <int_info> fpureg reg32 reg16 reg8 segreg
 %type <ea> mem memaddr memexp memfar
 %type <ea> mem8x mem16x mem32x mem64x mem80x mem128x
 %type <ea> mem8 mem16 mem32 mem64 mem80 mem128 mem1632
@@ -112,7 +117,8 @@ static bytecode *nasm_parser_temp_bc;
 %type <ea> rm8 rm16 rm32 rm64 rm128
 %type <im_val> imm imm8x imm16x imm32x imm8 imm16 imm32
 %type <exp> expr expr_no_string
-%type <str_val> explabel label_id
+%type <sym> explabel
+%type <str_val> label_id
 %type <tgt_val> target
 %type <data> dataval
 %type <datahead> datavals
@@ -164,7 +170,6 @@ datavals: dataval       {
 ;
 
 dataval: expr_no_string        { $$ = dataval_new_expr($1); }
-    | FLTNUM           { $$ = dataval_new_float($1); }
     | STRING           { $$ = dataval_new_string($1); }
     | error            {
        Error(_("expression syntax error"));
@@ -173,10 +178,12 @@ dataval: expr_no_string   { $$ = dataval_new_expr($1); }
 ;
 
 label: label_id            {
-       symrec_define_label($1, nasm_parser_cur_section, nasm_parser_prev_bc);
+       symrec_define_label($1, nasm_parser_cur_section, nasm_parser_prev_bc,
+                           1);
     }
     | label_id ':'  {
-       symrec_define_label($1, nasm_parser_cur_section, nasm_parser_prev_bc);
+       symrec_define_label($1, nasm_parser_cur_section, nasm_parser_prev_bc,
+                           1);
     }
 ;
 
@@ -194,6 +201,8 @@ directive: '[' DIRECTIVE_NAME DIRECTIVE_VAL ']'     {
            nasm_parser_cur_section = sections_switch(&nasm_parser_sections,
                                                      nasm_parser_objfmt, $3);
            nasm_parser_prev_bc = (bytecode *)NULL;
+           symrec_define_label($3, nasm_parser_cur_section, (bytecode *)NULL,
+                               1);
        } else {
            printf("Directive: Name='%s' Value='%s'\n", $2, $3);
        }
@@ -254,7 +263,7 @@ segreg:  REG_ES
 ;
 
 /* memory addresses */
-memexp: expr   { expr_simplify ($1); $$ = effaddr_new_expr($1); }
+memexp: expr   { $$ = effaddr_new_expr($1); }
 ;
 
 memaddr: memexp                    { $$ = $1; SetEASegment($$, 0); }
@@ -353,7 +362,7 @@ rm128: XMMREG       { $$ = effaddr_new_reg($1); }
 ;
 
 /* immediate values */
-imm: expr   { expr_simplify($1); $$ = immval_new_expr($1); }
+imm: expr   { $$ = immval_new_expr($1); }
 ;
 
 /* explicit immediates */
@@ -383,7 +392,8 @@ target: expr            { $$.val = $1; SetOpcodeSel(&$$.op_sel, JR_NONE); }
 
 /* expression trees */
 expr_no_string: INTNUM         { $$ = expr_new_ident(ExprInt($1)); }
-    | explabel                 { $$ = expr_new_ident(ExprSym(symrec_use($1))); }
+    | FLTNUM                   { $$ = expr_new_ident(ExprFloat($1)); }
+    | explabel                 { $$ = expr_new_ident(ExprSym($1)); }
     /*| expr '||' expr         { $$ = expr_new_tree($1, EXPR_LOR, $3); }*/
     | expr '|' expr            { $$ = expr_new_tree($1, EXPR_OR, $3); }
     | expr '^' expr            { $$ = expr_new_tree($1, EXPR_XOR, $3); }
@@ -401,7 +411,9 @@ expr_no_string: INTNUM              { $$ = expr_new_ident(ExprInt($1)); }
     | expr '-' expr            { $$ = expr_new_tree($1, EXPR_SUB, $3); }
     | expr '*' expr            { $$ = expr_new_tree($1, EXPR_MUL, $3); }
     | expr '/' expr            { $$ = expr_new_tree($1, EXPR_DIV, $3); }
+    | expr SIGNDIV expr                { $$ = expr_new_tree($1, EXPR_SIGNDIV, $3); }
     | expr '%' expr            { $$ = expr_new_tree($1, EXPR_MOD, $3); }
+    | expr SIGNMOD expr                { $$ = expr_new_tree($1, EXPR_SIGNMOD, $3); }
     | '+' expr %prec UNARYOP   { $$ = $2; }
     | '-' expr %prec UNARYOP   { $$ = expr_new_branch(EXPR_NEG, $2); }
     /*| '!' expr               { $$ = expr_new_branch(EXPR_LNOT, $2); }*/
@@ -411,13 +423,20 @@ expr_no_string: INTNUM            { $$ = expr_new_ident(ExprInt($1)); }
 
 expr: expr_no_string
     | STRING           {
-       $$ = expr_new_ident(ExprInt(ConvertCharConstToInt($1)));
+       $$ = expr_new_ident(ExprInt(intnum_new_charconst_nasm($1)));
     }
 ;
 
-explabel: ID
-    | SPECIAL_ID
-    | LOCAL_ID
+explabel: ID           { $$ = symrec_use($1); }
+    | SPECIAL_ID       { $$ = symrec_use($1); }
+    | LOCAL_ID         { $$ = symrec_use($1); }
+    | '$'              {
+       $$ = symrec_define_label("$", nasm_parser_cur_section,
+                                nasm_parser_prev_bc, 0);
+    }
+    | START_SECTION_ID {
+       $$ = symrec_use(section_get_name(nasm_parser_cur_section));
+    }
 ;
 
 instr: instrbase
@@ -440,32 +459,6 @@ instr: instrbase
 
 %%
 
-static unsigned long
-ConvertCharConstToInt(char *cc)
-{
-    unsigned long retval = 0;
-    size_t len = strlen(cc);
-
-    if (len > 4)
-       Warning(_("character constant too large, ignoring trailing characters"));
-
-    switch (len) {
-       case 4:
-           retval |= (unsigned long)cc[3];
-           retval <<= 8;
-       case 3:
-           retval |= (unsigned long)cc[2];
-           retval <<= 8;
-       case 2:
-           retval |= (unsigned long)cc[1];
-           retval <<= 8;
-       case 1:
-           retval |= (unsigned long)cc[0];
-    }
-
-    return retval;
-}
-
 void
 nasm_parser_error(const char *s)
 {
index c69c2e66ed7f236fe23eab7bfbc3062f0fbf8529..e44fcf456b57adf1390ff2a82ce62df8ff12afb9 100644 (file)
 #include <libintl.h>
 #define _(String)      gettext(String)
 
+#include "bitvect.h"
+
 #include "globals.h"
 #include "errwarn.h"
+#include "intnum.h"
 #include "floatnum.h"
 #include "expr.h"
 #include "symrec.h"
@@ -51,7 +54,6 @@ RCSID("$IdPath$");
 
 void init_table(void);
 extern int nasm_parser_lex(void);
-static unsigned long ConvertCharConstToInt(char *);
 void nasm_parser_error(const char *);
 
 extern objfmt *nasm_parser_objfmt;
@@ -65,9 +67,11 @@ static bytecode *nasm_parser_temp_bc;
 %}
 
 %union {
-    unsigned long int_val;
+    unsigned int int_info;
     char *str_val;
+    intnum *intn;
     floatnum *flt;
+    symrec *sym;
     unsigned char groupdata[4];
     effaddr *ea;
     expr *exp;
@@ -78,23 +82,24 @@ static bytecode *nasm_parser_temp_bc;
     bytecode *bc;
 }
 
-%token <int_val> INTNUM
+%token <intn> INTNUM
 %token <flt> FLTNUM
 %token <str_val> DIRECTIVE_NAME DIRECTIVE_VAL STRING
-%token <int_val> BYTE WORD DWORD QWORD TWORD DQWORD
-%token <int_val> DECLARE_DATA
-%token <int_val> RESERVE_SPACE
+%token <int_info> BYTE WORD DWORD QWORD TWORD DQWORD
+%token <int_info> DECLARE_DATA
+%token <int_info> RESERVE_SPACE
 %token INCBIN EQU TIMES
 %token SEG WRT NEAR SHORT FAR NOSPLIT ORG
 %token TO
 %token O16 O32 A16 A32 LOCK REPNZ REP REPZ
-%token <int_val> OPERSIZE ADDRSIZE
-%token <int_val> CR4 CRREG_NOTCR4 DRREG TRREG ST0 FPUREG_NOTST0 MMXREG XMMREG
-%token <int_val> REG_EAX REG_ECX REG_EDX REG_EBX REG_ESP REG_EBP REG_ESI REG_EDI
-%token <int_val> REG_AX REG_CX REG_DX REG_BX REG_SP REG_BP REG_SI REG_DI
-%token <int_val> REG_AL REG_CL REG_DL REG_BL REG_AH REG_CH REG_DH REG_BH
-%token <int_val> REG_ES REG_CS REG_SS REG_DS REG_FS REG_GS
-%token LEFT_OP RIGHT_OP SIGNDIV SIGNMOD
+%token <int_info> OPERSIZE ADDRSIZE
+%token <int_info> CR4 CRREG_NOTCR4 DRREG TRREG ST0 FPUREG_NOTST0 MMXREG XMMREG
+%token <int_info> REG_EAX REG_ECX REG_EDX REG_EBX
+%token <int_info> REG_ESP REG_EBP REG_ESI REG_EDI
+%token <int_info> REG_AX REG_CX REG_DX REG_BX REG_SP REG_BP REG_SI REG_DI
+%token <int_info> REG_AL REG_CL REG_DL REG_BL REG_AH REG_CH REG_DH REG_BH
+%token <int_info> REG_ES REG_CS REG_SS REG_DS REG_FS REG_GS
+%token LEFT_OP RIGHT_OP SIGNDIV SIGNMOD START_SECTION_ID
 %token <str_val> ID LOCAL_ID SPECIAL_ID
 
 /* instruction tokens (dynamically generated) */
@@ -102,9 +107,9 @@ static bytecode *nasm_parser_temp_bc;
 
 /* @TYPES@ */
 
-%type <bc> line exp instr instrbase label
+%type <bc> line exp instr instrbase
 
-%type <int_val> fpureg reg32 reg16 reg8 segreg
+%type <int_info> fpureg reg32 reg16 reg8 segreg
 %type <ea> mem memaddr memexp memfar
 %type <ea> mem8x mem16x mem32x mem64x mem80x mem128x
 %type <ea> mem8 mem16 mem32 mem64 mem80 mem128 mem1632
@@ -112,7 +117,8 @@ static bytecode *nasm_parser_temp_bc;
 %type <ea> rm8 rm16 rm32 rm64 rm128
 %type <im_val> imm imm8x imm16x imm32x imm8 imm16 imm32
 %type <exp> expr expr_no_string
-%type <str_val> explabel label_id
+%type <sym> explabel
+%type <str_val> label_id
 %type <tgt_val> target
 %type <data> dataval
 %type <datahead> datavals
@@ -164,7 +170,6 @@ datavals: dataval       {
 ;
 
 dataval: expr_no_string        { $$ = dataval_new_expr($1); }
-    | FLTNUM           { $$ = dataval_new_float($1); }
     | STRING           { $$ = dataval_new_string($1); }
     | error            {
        Error(_("expression syntax error"));
@@ -173,10 +178,12 @@ dataval: expr_no_string   { $$ = dataval_new_expr($1); }
 ;
 
 label: label_id            {
-       symrec_define_label($1, nasm_parser_cur_section, nasm_parser_prev_bc);
+       symrec_define_label($1, nasm_parser_cur_section, nasm_parser_prev_bc,
+                           1);
     }
     | label_id ':'  {
-       symrec_define_label($1, nasm_parser_cur_section, nasm_parser_prev_bc);
+       symrec_define_label($1, nasm_parser_cur_section, nasm_parser_prev_bc,
+                           1);
     }
 ;
 
@@ -194,6 +201,8 @@ directive: '[' DIRECTIVE_NAME DIRECTIVE_VAL ']'     {
            nasm_parser_cur_section = sections_switch(&nasm_parser_sections,
                                                      nasm_parser_objfmt, $3);
            nasm_parser_prev_bc = (bytecode *)NULL;
+           symrec_define_label($3, nasm_parser_cur_section, (bytecode *)NULL,
+                               1);
        } else {
            printf("Directive: Name='%s' Value='%s'\n", $2, $3);
        }
@@ -254,7 +263,7 @@ segreg:  REG_ES
 ;
 
 /* memory addresses */
-memexp: expr   { expr_simplify ($1); $$ = effaddr_new_expr($1); }
+memexp: expr   { $$ = effaddr_new_expr($1); }
 ;
 
 memaddr: memexp                    { $$ = $1; SetEASegment($$, 0); }
@@ -353,7 +362,7 @@ rm128: XMMREG       { $$ = effaddr_new_reg($1); }
 ;
 
 /* immediate values */
-imm: expr   { expr_simplify($1); $$ = immval_new_expr($1); }
+imm: expr   { $$ = immval_new_expr($1); }
 ;
 
 /* explicit immediates */
@@ -383,7 +392,8 @@ target: expr            { $$.val = $1; SetOpcodeSel(&$$.op_sel, JR_NONE); }
 
 /* expression trees */
 expr_no_string: INTNUM         { $$ = expr_new_ident(ExprInt($1)); }
-    | explabel                 { $$ = expr_new_ident(ExprSym(symrec_use($1))); }
+    | FLTNUM                   { $$ = expr_new_ident(ExprFloat($1)); }
+    | explabel                 { $$ = expr_new_ident(ExprSym($1)); }
     /*| expr '||' expr         { $$ = expr_new_tree($1, EXPR_LOR, $3); }*/
     | expr '|' expr            { $$ = expr_new_tree($1, EXPR_OR, $3); }
     | expr '^' expr            { $$ = expr_new_tree($1, EXPR_XOR, $3); }
@@ -401,7 +411,9 @@ expr_no_string: INTNUM              { $$ = expr_new_ident(ExprInt($1)); }
     | expr '-' expr            { $$ = expr_new_tree($1, EXPR_SUB, $3); }
     | expr '*' expr            { $$ = expr_new_tree($1, EXPR_MUL, $3); }
     | expr '/' expr            { $$ = expr_new_tree($1, EXPR_DIV, $3); }
+    | expr SIGNDIV expr                { $$ = expr_new_tree($1, EXPR_SIGNDIV, $3); }
     | expr '%' expr            { $$ = expr_new_tree($1, EXPR_MOD, $3); }
+    | expr SIGNMOD expr                { $$ = expr_new_tree($1, EXPR_SIGNMOD, $3); }
     | '+' expr %prec UNARYOP   { $$ = $2; }
     | '-' expr %prec UNARYOP   { $$ = expr_new_branch(EXPR_NEG, $2); }
     /*| '!' expr               { $$ = expr_new_branch(EXPR_LNOT, $2); }*/
@@ -411,13 +423,20 @@ expr_no_string: INTNUM            { $$ = expr_new_ident(ExprInt($1)); }
 
 expr: expr_no_string
     | STRING           {
-       $$ = expr_new_ident(ExprInt(ConvertCharConstToInt($1)));
+       $$ = expr_new_ident(ExprInt(intnum_new_charconst_nasm($1)));
     }
 ;
 
-explabel: ID
-    | SPECIAL_ID
-    | LOCAL_ID
+explabel: ID           { $$ = symrec_use($1); }
+    | SPECIAL_ID       { $$ = symrec_use($1); }
+    | LOCAL_ID         { $$ = symrec_use($1); }
+    | '$'              {
+       $$ = symrec_define_label("$", nasm_parser_cur_section,
+                                nasm_parser_prev_bc, 0);
+    }
+    | START_SECTION_ID {
+       $$ = symrec_use(section_get_name(nasm_parser_cur_section));
+    }
 ;
 
 instr: instrbase
@@ -440,32 +459,6 @@ instr: instrbase
 
 %%
 
-static unsigned long
-ConvertCharConstToInt(char *cc)
-{
-    unsigned long retval = 0;
-    size_t len = strlen(cc);
-
-    if (len > 4)
-       Warning(_("character constant too large, ignoring trailing characters"));
-
-    switch (len) {
-       case 4:
-           retval |= (unsigned long)cc[3];
-           retval <<= 8;
-       case 3:
-           retval |= (unsigned long)cc[2];
-           retval <<= 8;
-       case 2:
-           retval |= (unsigned long)cc[1];
-           retval <<= 8;
-       case 1:
-           retval |= (unsigned long)cc[0];
-    }
-
-    return retval;
-}
-
 void
 nasm_parser_error(const char *s)
 {
index 5329e1b4890575b1fb3bb1bb0254dee29c97d672..17c4a99681afa3819d30b6f8c5a206a73ce8ea4b 100644 (file)
 #include <libintl.h>
 #define _(String)      gettext(String)
 
+#include "bitvect.h"
+
 #include "errwarn.h"
+#include "intnum.h"
 #include "floatnum.h"
 #include "expr.h"
 #include "symrec.h"
@@ -87,31 +90,37 @@ WS       [ \t\r]
 
     /* standard decimal integer */
 {DIGIT}+ {
-    yylval.int_val = strtoul(yytext, (char **)NULL, 10);
+    yylval.intn = intnum_new_dec(yytext);
     return INTNUM;
 }
 
     /* 10010011b - binary number */
 {BINDIGIT}+b {
-    yylval.int_val = strtoul(yytext, (char **)NULL, 2);
+    yytext[strlen(yytext)] = '\0';  /* strip off 'b' */
+    yylval.intn = intnum_new_bin(yytext);
     return INTNUM;
 }
 
     /* 777q - octal number */
 {OCTDIGIT}+q {
-    yylval.int_val = strtoul(yytext, (char **)NULL, 8);
+    yytext[strlen(yytext)] = '\0';  /* strip off 'q' */
+    yylval.intn = intnum_new_oct(yytext);
     return INTNUM;
 }
 
     /* 0AAh form of hexidecimal number */
 0{HEXDIGIT}+h {
-    yylval.int_val = strtoul(yytext+1, (char **)NULL, 16);
+    yytext[strlen(yytext)] = '\0';  /* strip off 'h' */
+    yylval.intn = intnum_new_hex(yytext);
     return INTNUM;
 }
 
     /* $0AA and 0xAA forms of hexidecimal number */
 (\$0|0x){HEXDIGIT}+ {
-    yylval.int_val = strtoul(yytext+2, (char **)NULL, 16);
+    if (yytext[1] == 'x')
+       yylval.intn = intnum_new_hex(yytext+2); /* 0x format, skip 0 and x */
+    else
+       yylval.intn = intnum_new_hex(yytext+1); /* $0 format, don't skip 0 */
     return INTNUM;
 }
 
@@ -182,25 +191,25 @@ WS       [ \t\r]
 }
 
     /* size specifiers */
-byte   { yylval.int_val = 1; return BYTE; }
-word   { yylval.int_val = 2; return WORD; }
-dword  { yylval.int_val = 4; return DWORD; }
-qword  { yylval.int_val = 8; return QWORD; }
-tword  { yylval.int_val = 10; return TWORD; }
-dqword { yylval.int_val = 16; return DQWORD; }
+byte   { yylval.int_info = 1; return BYTE; }
+word   { yylval.int_info = 2; return WORD; }
+dword  { yylval.int_info = 4; return DWORD; }
+qword  { yylval.int_info = 8; return QWORD; }
+tword  { yylval.int_info = 10; return TWORD; }
+dqword { yylval.int_info = 16; return DQWORD; }
 
     /* pseudo-instructions */
-db     { yylval.int_val = 1; return DECLARE_DATA; }
-dw     { yylval.int_val = 2; return DECLARE_DATA; }
-dd     { yylval.int_val = 4; return DECLARE_DATA; }
-dq     { yylval.int_val = 8; return DECLARE_DATA; }
-dt     { yylval.int_val = 10; return DECLARE_DATA; }
-
-resb   { yylval.int_val = 1; return RESERVE_SPACE; }
-resw   { yylval.int_val = 2; return RESERVE_SPACE; }
-resd   { yylval.int_val = 4; return RESERVE_SPACE; }
-resq   { yylval.int_val = 8; return RESERVE_SPACE; }
-rest   { yylval.int_val = 10; return RESERVE_SPACE; }
+db     { yylval.int_info = 1; return DECLARE_DATA; }
+dw     { yylval.int_info = 2; return DECLARE_DATA; }
+dd     { yylval.int_info = 4; return DECLARE_DATA; }
+dq     { yylval.int_info = 8; return DECLARE_DATA; }
+dt     { yylval.int_info = 10; return DECLARE_DATA; }
+
+resb   { yylval.int_info = 1; return RESERVE_SPACE; }
+resw   { yylval.int_info = 2; return RESERVE_SPACE; }
+resd   { yylval.int_info = 4; return RESERVE_SPACE; }
+resq   { yylval.int_info = 8; return RESERVE_SPACE; }
+rest   { yylval.int_info = 10; return RESERVE_SPACE; }
 
 incbin { return INCBIN; }
 
@@ -221,11 +230,11 @@ org       { return ORG; }
 to     { return TO; }
 
     /* operand size overrides */
-o16    { yylval.int_val = 16; return OPERSIZE; }
-o32    { yylval.int_val = 32; return OPERSIZE; }
+o16    { yylval.int_info = 16; return OPERSIZE; }
+o32    { yylval.int_info = 32; return OPERSIZE; }
     /* address size overrides */
-a16    { yylval.int_val = 16; return ADDRSIZE; }
-a32    { yylval.int_val = 32; return ADDRSIZE; }
+a16    { yylval.int_info = 16; return ADDRSIZE; }
+a32    { yylval.int_info = 32; return ADDRSIZE; }
 
     /* instruction prefixes */
 lock   { return LOCK; }
@@ -236,62 +245,63 @@ repe      { return REPZ; }
 repz   { return REPZ; }
 
     /* control, debug, and test registers */
-cr4            { yylval.int_val = 4; return CR4; }
-cr[023]                { yylval.int_val = yytext[2]-'0'; return CRREG_NOTCR4; }
-dr[0-367]      { yylval.int_val = yytext[2]-'0'; return DRREG; }
-tr[3-7]                { yylval.int_val = yytext[2]-'0'; return TRREG; }
+cr4            { yylval.int_info = 4; return CR4; }
+cr[023]                { yylval.int_info = yytext[2]-'0'; return CRREG_NOTCR4; }
+dr[0-367]      { yylval.int_info = yytext[2]-'0'; return DRREG; }
+tr[3-7]                { yylval.int_info = yytext[2]-'0'; return TRREG; }
 
     /* floating point, MMX, and SSE registers */
-st0        { yylval.int_val = 0; return ST0; }
-st[1-7]            { yylval.int_val = yytext[2]-'0'; return FPUREG_NOTST0; }
-mm[0-7]            { yylval.int_val = yytext[2]-'0'; return MMXREG; }
-xmm[0-7]    { yylval.int_val = yytext[3]-'0'; return XMMREG; }
+st0        { yylval.int_info = 0; return ST0; }
+st[1-7]            { yylval.int_info = yytext[2]-'0'; return FPUREG_NOTST0; }
+mm[0-7]            { yylval.int_info = yytext[2]-'0'; return MMXREG; }
+xmm[0-7]    { yylval.int_info = yytext[3]-'0'; return XMMREG; }
 
     /* integer registers */
-eax    { yylval.int_val = 0; return REG_EAX; }
-ecx    { yylval.int_val = 1; return REG_ECX; }
-edx    { yylval.int_val = 2; return REG_EDX; }
-ebx    { yylval.int_val = 3; return REG_EBX; }
-esp    { yylval.int_val = 4; return REG_ESP; }
-ebp    { yylval.int_val = 5; return REG_EBP; }
-esi    { yylval.int_val = 6; return REG_ESI; }
-edi    { yylval.int_val = 7; return REG_EDI; }
-
-ax     { yylval.int_val = 0; return REG_AX; }
-cx     { yylval.int_val = 1; return REG_CX; }
-dx     { yylval.int_val = 2; return REG_DX; }
-bx     { yylval.int_val = 3; return REG_BX; }
-sp     { yylval.int_val = 4; return REG_SP; }
-bp     { yylval.int_val = 5; return REG_BP; }
-si     { yylval.int_val = 6; return REG_SI; }
-di     { yylval.int_val = 7; return REG_DI; }
-
-al     { yylval.int_val = 0; return REG_AL; }
-cl     { yylval.int_val = 1; return REG_CL; }
-dl     { yylval.int_val = 2; return REG_DL; }
-bl     { yylval.int_val = 3; return REG_BL; }
-ah     { yylval.int_val = 4; return REG_AH; }
-ch     { yylval.int_val = 5; return REG_CH; }
-dh     { yylval.int_val = 6; return REG_DH; }
-bh     { yylval.int_val = 7; return REG_BH; }
+eax    { yylval.int_info = 0; return REG_EAX; }
+ecx    { yylval.int_info = 1; return REG_ECX; }
+edx    { yylval.int_info = 2; return REG_EDX; }
+ebx    { yylval.int_info = 3; return REG_EBX; }
+esp    { yylval.int_info = 4; return REG_ESP; }
+ebp    { yylval.int_info = 5; return REG_EBP; }
+esi    { yylval.int_info = 6; return REG_ESI; }
+edi    { yylval.int_info = 7; return REG_EDI; }
+
+ax     { yylval.int_info = 0; return REG_AX; }
+cx     { yylval.int_info = 1; return REG_CX; }
+dx     { yylval.int_info = 2; return REG_DX; }
+bx     { yylval.int_info = 3; return REG_BX; }
+sp     { yylval.int_info = 4; return REG_SP; }
+bp     { yylval.int_info = 5; return REG_BP; }
+si     { yylval.int_info = 6; return REG_SI; }
+di     { yylval.int_info = 7; return REG_DI; }
+
+al     { yylval.int_info = 0; return REG_AL; }
+cl     { yylval.int_info = 1; return REG_CL; }
+dl     { yylval.int_info = 2; return REG_DL; }
+bl     { yylval.int_info = 3; return REG_BL; }
+ah     { yylval.int_info = 4; return REG_AH; }
+ch     { yylval.int_info = 5; return REG_CH; }
+dh     { yylval.int_info = 6; return REG_DH; }
+bh     { yylval.int_info = 7; return REG_BH; }
 
     /* segment registers */
-es     { yylval.int_val = 0; return REG_ES; }
-cs     { yylval.int_val = 1; return REG_CS; }
-ss     { yylval.int_val = 2; return REG_SS; }
-ds     { yylval.int_val = 3; return REG_DS; }
-fs     { yylval.int_val = 4; return REG_FS; }
-gs     { yylval.int_val = 5; return REG_GS; }
+es     { yylval.int_info = 0; return REG_ES; }
+cs     { yylval.int_info = 1; return REG_CS; }
+ss     { yylval.int_info = 2; return REG_SS; }
+ds     { yylval.int_info = 3; return REG_DS; }
+fs     { yylval.int_info = 4; return REG_FS; }
+gs     { yylval.int_info = 5; return REG_GS; }
 
     /* operators */
 "<<"                   { return LEFT_OP; }
 ">>"                   { return RIGHT_OP; }
 "//"                   { return SIGNDIV; }
 "%%"                   { return SIGNMOD; }
-[-+|^&*/%~():[\],]     { return yytext[0]; }
+"$$"                   { return START_SECTION_ID; }
+[-+|^&*/%~$():[\],]    { return yytext[0]; }
 
     /* special non-local ..@label and labels like ..start */
-$$|$|\.\.[a-z0-9_$#@~.?]+ {
+\.\.[a-z0-9_$#@~.?]+ {
     yylval.str_val = xstrdup(yytext);
     return SPECIAL_ID;
 }
index 41a5782ec0272a819835c993629a9471d063b6b6..16dc899847dcfa808ed188e028ade041892069a8 100644 (file)
@@ -41,6 +41,8 @@ libyasm_a_SOURCES = \
        parser.c                \
        parser.h                \
        optimizer.h             \
+       intnum.c                \
+       intnum.h                \
        floatnum.c              \
        floatnum.h              \
        ternary.c               \
@@ -55,5 +57,4 @@ CFLAGS = @ANSI_CFLAGS@
 
 EXTRA_DIST = \
        instrs.dat              \
-       compat-queue.h          \
-       strtoul.c
+       compat-queue.h
index 911fe47dd75f1ae4e494f5cac1889ad456a607d5..252065f738b874426ff4d93aa996c0a79ef8b433 100644 (file)
 #define N_(String)     (String)
 #endif
 
+#include "bitvect.h"
+
 #include "globals.h"
 #include "errwarn.h"
+#include "intnum.h"
 #include "floatnum.h"
 #include "expr.h"
 #include "symrec.h"
@@ -61,7 +64,7 @@ struct ExprItem {
     union {
        symrec *sym;
        expr *expn;
-       unsigned long int_val;
+       intnum *intn;
        floatnum *flt;
     } data;
 };
@@ -69,6 +72,8 @@ struct ExprItem {
 struct expr {
     ExprItem left, right;
     ExprOp op;
+    char *filename;
+    unsigned long line;
 };
 
 /* allocate a new expression node, with children as defined.
@@ -93,6 +98,10 @@ expr_new(ExprItem *left, ExprOp op, ExprItem *right)
        InternalError(__LINE__, __FILE__,
                      _("Right side of expression must exist"));
     }
+
+    ptr->filename = xstrdup(in_filename);
+    ptr->line = line_number;
+
     return ptr;
 }
 
@@ -116,11 +125,11 @@ ExprExpr(expr *x)
 }
 
 ExprItem *
-ExprInt(unsigned long i)
+ExprInt(intnum *i)
 {
     ExprItem *e = xmalloc(sizeof(ExprItem));
     e->type = EXPR_INT;
-    e->data.int_val = i;
+    e->data.intn = i;
     return e;
 }
 
@@ -138,7 +147,7 @@ int
 expr_simplify(expr *e)
 {
     int simplified = 0;
-    unsigned long int_val;
+    ExprItem tmp;
 
     /* try to simplify the left side */
     if (e->left.type == EXPR_EXPR) {
@@ -150,14 +159,14 @@ expr_simplify(expr *e)
         * pull it up into the current node */
        while (e->left.type == EXPR_EXPR &&
               e->left.data.expn->op == EXPR_IDENT) {
-           ExprItem tmp;
-           e->left.type = e->left.data.expn->right.type;
            memcpy(&tmp, &(e->left.data.expn->right), sizeof(ExprItem));
            free(e->left.data.expn);
-           memcpy(&(e->left.data.int_val), &tmp, sizeof(ExprItem));
+           memcpy(&e->left, &tmp, sizeof(ExprItem));
            simplified = 1;
        }
-    } else if (e->left.type == EXPR_SYM) {
+    }
+#if 0
+    else if (e->left.type == EXPR_SYM) {
        /* try to get value of symbol */
        if (symrec_get_int_value(e->left.data.sym, &int_val, 0)) {
            e->left.type = EXPR_INT;
@@ -166,6 +175,7 @@ expr_simplify(expr *e)
            simplified = 1;
        }
     }
+#endif
 
     /* ditto on the right */
     if (e->right.type == EXPR_EXPR) {
@@ -174,14 +184,14 @@ expr_simplify(expr *e)
 
        while (e->right.type == EXPR_EXPR &&
               e->right.data.expn->op == EXPR_IDENT) {
-           ExprItem tmp;
-           e->right.type = e->right.data.expn->right.type;
            memcpy(&tmp, &(e->right.data.expn->right), sizeof(ExprItem));
            free(e->right.data.expn);
-           memcpy(&(e->right.data.int_val), &tmp, sizeof(ExprItem));
+           memcpy(&e->right, &tmp, sizeof(ExprItem));
            simplified = 1;
        }
-    } else if (e->right.type == EXPR_SYM) {
+    }
+#if 0
+    else if (e->right.type == EXPR_SYM) {
        if (symrec_get_int_value(e->right.data.sym, &int_val, 0)) {
            e->right.type = EXPR_INT;
            /* don't try to free the symrec here. */
@@ -189,139 +199,45 @@ expr_simplify(expr *e)
            simplified = 1;
        }
     }
-
-    if ((e->left.type == EXPR_INT || e->left.type == EXPR_NONE) &&
-       e->right.type == EXPR_INT && e->op != EXPR_IDENT) {
-       switch (e->op) {
-           case EXPR_ADD:
-               e->right.data.int_val = e->left.data.int_val +
-                                       e->right.data.int_val;
-               break;
-           case EXPR_SUB:
-               e->right.data.int_val = e->left.data.int_val -
-                                       e->right.data.int_val;
-               break;
-           case EXPR_MUL:
-               e->right.data.int_val = e->left.data.int_val *
-                                       e->right.data.int_val;
-               break;
-           case EXPR_DIV:
-               e->right.data.int_val = e->left.data.int_val /
-                                       e->right.data.int_val;
-               break;
-           case EXPR_MOD:
-               e->right.data.int_val = e->left.data.int_val %
-                                       e->right.data.int_val;
-               break;
-           case EXPR_NEG:
-               e->right.data.int_val = -(e->right.data.int_val);
-               break;
-           case EXPR_NOT:
-               e->right.data.int_val = ~(e->right.data.int_val);
-               break;
-           case EXPR_OR:
-               e->right.data.int_val = e->left.data.int_val |
-                                       e->right.data.int_val;
-               break;
-           case EXPR_AND:
-               e->right.data.int_val = e->left.data.int_val &
-                                       e->right.data.int_val;
-               break;
-           case EXPR_XOR:
-               e->right.data.int_val = e->left.data.int_val ^
-                                       e->right.data.int_val;
-               break;
-           case EXPR_SHL:
-               e->right.data.int_val = e->right.data.int_val <<
-                                       e->left.data.int_val;
-               break;
-           case EXPR_SHR:
-               e->right.data.int_val = e->right.data.int_val >>
-                                       e->left.data.int_val;
-               break;
-           case EXPR_LOR:
-               e->right.data.int_val = e->left.data.int_val ||
-                                       e->right.data.int_val;
-               break;
-           case EXPR_LAND:
-               e->right.data.int_val = e->left.data.int_val &&
-                                       e->right.data.int_val;
-               break;
-           case EXPR_LNOT:
-               e->right.data.int_val = !e->right.data.int_val;
-               break;
-           case EXPR_EQ:
-               e->right.data.int_val = e->right.data.int_val ==
-                                       e->left.data.int_val;
-               break;
-           case EXPR_LT:
-               e->right.data.int_val = e->right.data.int_val <
-                                       e->left.data.int_val;
-               break;
-           case EXPR_GT:
-               e->right.data.int_val = e->right.data.int_val >
-                                       e->left.data.int_val;
-               break;
-           case EXPR_LE:
-               e->right.data.int_val = e->right.data.int_val <=
-                                       e->left.data.int_val;
-               break;
-           case EXPR_GE:
-               e->right.data.int_val = e->right.data.int_val >=
-                                       e->left.data.int_val;
-               break;
-           case EXPR_NE:
-               e->right.data.int_val = e->right.data.int_val !=
-                                       e->left.data.int_val;
-               break;
-           case EXPR_IDENT:
-               break;
-       }
-       e->op = EXPR_IDENT;
-       simplified = 1;
-    }
+#endif
 
     /* catch simple identities like 0+x, 1*x, etc., for x not a num */
-    else if (e->left.type == EXPR_INT &&
-            ((e->left.data.int_val == 1 && e->op == EXPR_MUL) ||
-             (e->left.data.int_val == 0 && e->op == EXPR_ADD) ||
-             (e->left.data.int_val == -1 && e->op == EXPR_AND) ||
-             (e->left.data.int_val == 0 && e->op == EXPR_OR))) {
+    if (e->left.type == EXPR_INT &&
+            ((intnum_is_pos1(e->left.data.intn) && e->op == EXPR_MUL) ||
+             (intnum_is_zero(e->left.data.intn) && e->op == EXPR_ADD) ||
+             (intnum_is_neg1(e->left.data.intn) && e->op == EXPR_AND) ||
+             (intnum_is_zero(e->left.data.intn) && e->op == EXPR_OR))) {
+       intnum_delete(e->left.data.intn);
        e->op = EXPR_IDENT;
        simplified = 1;
     }
     /* and the corresponding x+|-0, x*&/1 */
     else if (e->right.type == EXPR_INT &&
-            ((e->right.data.int_val == 1 && e->op == EXPR_MUL) ||
-             (e->right.data.int_val == 1 && e->op == EXPR_DIV) ||
-             (e->right.data.int_val == 0 && e->op == EXPR_ADD) ||
-             (e->right.data.int_val == 0 && e->op == EXPR_SUB) ||
-             (e->right.data.int_val == -1 && e->op == EXPR_AND) ||
-             (e->right.data.int_val == 0 && e->op == EXPR_OR) ||
-             (e->right.data.int_val == 0 && e->op == EXPR_SHL) ||
-             (e->right.data.int_val == 0 && e->op == EXPR_SHR))) {
+            ((intnum_is_pos1(e->right.data.intn) && e->op == EXPR_MUL) ||
+             (intnum_is_pos1(e->right.data.intn) && e->op == EXPR_DIV) ||
+             (intnum_is_zero(e->right.data.intn) && e->op == EXPR_ADD) ||
+             (intnum_is_zero(e->right.data.intn) && e->op == EXPR_SUB) ||
+             (intnum_is_neg1(e->right.data.intn) && e->op == EXPR_AND) ||
+             (intnum_is_zero(e->right.data.intn) && e->op == EXPR_OR) ||
+             (intnum_is_zero(e->right.data.intn) && e->op == EXPR_SHL) ||
+             (intnum_is_zero(e->right.data.intn) && e->op == EXPR_SHR))) {
+       intnum_delete(e->right.data.intn);
        e->op = EXPR_IDENT;
        e->right.type = e->left.type;
        memcpy(&e->right, &e->left, sizeof(ExprItem));
        simplified = 1;
+    } else if ((e->left.type == EXPR_INT || e->left.type == EXPR_NONE) &&
+       e->right.type == EXPR_INT && e->op != EXPR_IDENT) {
+       intnum_calc(e->left.data.intn, e->op, e->right.data.intn);
+       intnum_delete(e->right.data.intn);
+       e->right.data.intn = e->left.data.intn;
+       e->op = EXPR_IDENT;
+       simplified = 1;
     }
 
     return simplified;
 }
 
-int
-expr_get_value(expr *e, unsigned long *retval)
-{
-    while (!(e->op == EXPR_IDENT && e->right.type == EXPR_INT)
-          && expr_simplify(e)) ;
-
-    if (e->op == EXPR_IDENT && e->right.type == EXPR_INT) {
-       *retval = e->right.data.int_val;
-       return 1;
-    } else
-       return 0;
-}
-
 void
 expr_print(expr *e)
 {
@@ -336,7 +252,7 @@ expr_print(expr *e)
                printf(")");
                break;
            case EXPR_INT:
-               printf("%lu", e->left.data.int_val);
+               intnum_print(e->left.data.intn);
                break;
            case EXPR_FLOAT:
                floatnum_print(e->left.data.flt);
@@ -358,9 +274,15 @@ expr_print(expr *e)
        case EXPR_DIV:
            printf("/");
            break;
+       case EXPR_SIGNDIV:
+           printf("//");
+           break;
        case EXPR_MOD:
            printf("%%");
            break;
+       case EXPR_SIGNMOD:
+           printf("%%%%");
+           break;
        case EXPR_NEG:
            printf("-");
            break;
@@ -422,7 +344,7 @@ expr_print(expr *e)
            printf(")");
            break;
        case EXPR_INT:
-           printf("%lu", e->right.data.int_val);
+           intnum_print(e->right.data.intn);
            break;
        case EXPR_FLOAT:
            floatnum_print(e->right.data.flt);
index 911fe47dd75f1ae4e494f5cac1889ad456a607d5..252065f738b874426ff4d93aa996c0a79ef8b433 100644 (file)
 #define N_(String)     (String)
 #endif
 
+#include "bitvect.h"
+
 #include "globals.h"
 #include "errwarn.h"
+#include "intnum.h"
 #include "floatnum.h"
 #include "expr.h"
 #include "symrec.h"
@@ -61,7 +64,7 @@ struct ExprItem {
     union {
        symrec *sym;
        expr *expn;
-       unsigned long int_val;
+       intnum *intn;
        floatnum *flt;
     } data;
 };
@@ -69,6 +72,8 @@ struct ExprItem {
 struct expr {
     ExprItem left, right;
     ExprOp op;
+    char *filename;
+    unsigned long line;
 };
 
 /* allocate a new expression node, with children as defined.
@@ -93,6 +98,10 @@ expr_new(ExprItem *left, ExprOp op, ExprItem *right)
        InternalError(__LINE__, __FILE__,
                      _("Right side of expression must exist"));
     }
+
+    ptr->filename = xstrdup(in_filename);
+    ptr->line = line_number;
+
     return ptr;
 }
 
@@ -116,11 +125,11 @@ ExprExpr(expr *x)
 }
 
 ExprItem *
-ExprInt(unsigned long i)
+ExprInt(intnum *i)
 {
     ExprItem *e = xmalloc(sizeof(ExprItem));
     e->type = EXPR_INT;
-    e->data.int_val = i;
+    e->data.intn = i;
     return e;
 }
 
@@ -138,7 +147,7 @@ int
 expr_simplify(expr *e)
 {
     int simplified = 0;
-    unsigned long int_val;
+    ExprItem tmp;
 
     /* try to simplify the left side */
     if (e->left.type == EXPR_EXPR) {
@@ -150,14 +159,14 @@ expr_simplify(expr *e)
         * pull it up into the current node */
        while (e->left.type == EXPR_EXPR &&
               e->left.data.expn->op == EXPR_IDENT) {
-           ExprItem tmp;
-           e->left.type = e->left.data.expn->right.type;
            memcpy(&tmp, &(e->left.data.expn->right), sizeof(ExprItem));
            free(e->left.data.expn);
-           memcpy(&(e->left.data.int_val), &tmp, sizeof(ExprItem));
+           memcpy(&e->left, &tmp, sizeof(ExprItem));
            simplified = 1;
        }
-    } else if (e->left.type == EXPR_SYM) {
+    }
+#if 0
+    else if (e->left.type == EXPR_SYM) {
        /* try to get value of symbol */
        if (symrec_get_int_value(e->left.data.sym, &int_val, 0)) {
            e->left.type = EXPR_INT;
@@ -166,6 +175,7 @@ expr_simplify(expr *e)
            simplified = 1;
        }
     }
+#endif
 
     /* ditto on the right */
     if (e->right.type == EXPR_EXPR) {
@@ -174,14 +184,14 @@ expr_simplify(expr *e)
 
        while (e->right.type == EXPR_EXPR &&
               e->right.data.expn->op == EXPR_IDENT) {
-           ExprItem tmp;
-           e->right.type = e->right.data.expn->right.type;
            memcpy(&tmp, &(e->right.data.expn->right), sizeof(ExprItem));
            free(e->right.data.expn);
-           memcpy(&(e->right.data.int_val), &tmp, sizeof(ExprItem));
+           memcpy(&e->right, &tmp, sizeof(ExprItem));
            simplified = 1;
        }
-    } else if (e->right.type == EXPR_SYM) {
+    }
+#if 0
+    else if (e->right.type == EXPR_SYM) {
        if (symrec_get_int_value(e->right.data.sym, &int_val, 0)) {
            e->right.type = EXPR_INT;
            /* don't try to free the symrec here. */
@@ -189,139 +199,45 @@ expr_simplify(expr *e)
            simplified = 1;
        }
     }
-
-    if ((e->left.type == EXPR_INT || e->left.type == EXPR_NONE) &&
-       e->right.type == EXPR_INT && e->op != EXPR_IDENT) {
-       switch (e->op) {
-           case EXPR_ADD:
-               e->right.data.int_val = e->left.data.int_val +
-                                       e->right.data.int_val;
-               break;
-           case EXPR_SUB:
-               e->right.data.int_val = e->left.data.int_val -
-                                       e->right.data.int_val;
-               break;
-           case EXPR_MUL:
-               e->right.data.int_val = e->left.data.int_val *
-                                       e->right.data.int_val;
-               break;
-           case EXPR_DIV:
-               e->right.data.int_val = e->left.data.int_val /
-                                       e->right.data.int_val;
-               break;
-           case EXPR_MOD:
-               e->right.data.int_val = e->left.data.int_val %
-                                       e->right.data.int_val;
-               break;
-           case EXPR_NEG:
-               e->right.data.int_val = -(e->right.data.int_val);
-               break;
-           case EXPR_NOT:
-               e->right.data.int_val = ~(e->right.data.int_val);
-               break;
-           case EXPR_OR:
-               e->right.data.int_val = e->left.data.int_val |
-                                       e->right.data.int_val;
-               break;
-           case EXPR_AND:
-               e->right.data.int_val = e->left.data.int_val &
-                                       e->right.data.int_val;
-               break;
-           case EXPR_XOR:
-               e->right.data.int_val = e->left.data.int_val ^
-                                       e->right.data.int_val;
-               break;
-           case EXPR_SHL:
-               e->right.data.int_val = e->right.data.int_val <<
-                                       e->left.data.int_val;
-               break;
-           case EXPR_SHR:
-               e->right.data.int_val = e->right.data.int_val >>
-                                       e->left.data.int_val;
-               break;
-           case EXPR_LOR:
-               e->right.data.int_val = e->left.data.int_val ||
-                                       e->right.data.int_val;
-               break;
-           case EXPR_LAND:
-               e->right.data.int_val = e->left.data.int_val &&
-                                       e->right.data.int_val;
-               break;
-           case EXPR_LNOT:
-               e->right.data.int_val = !e->right.data.int_val;
-               break;
-           case EXPR_EQ:
-               e->right.data.int_val = e->right.data.int_val ==
-                                       e->left.data.int_val;
-               break;
-           case EXPR_LT:
-               e->right.data.int_val = e->right.data.int_val <
-                                       e->left.data.int_val;
-               break;
-           case EXPR_GT:
-               e->right.data.int_val = e->right.data.int_val >
-                                       e->left.data.int_val;
-               break;
-           case EXPR_LE:
-               e->right.data.int_val = e->right.data.int_val <=
-                                       e->left.data.int_val;
-               break;
-           case EXPR_GE:
-               e->right.data.int_val = e->right.data.int_val >=
-                                       e->left.data.int_val;
-               break;
-           case EXPR_NE:
-               e->right.data.int_val = e->right.data.int_val !=
-                                       e->left.data.int_val;
-               break;
-           case EXPR_IDENT:
-               break;
-       }
-       e->op = EXPR_IDENT;
-       simplified = 1;
-    }
+#endif
 
     /* catch simple identities like 0+x, 1*x, etc., for x not a num */
-    else if (e->left.type == EXPR_INT &&
-            ((e->left.data.int_val == 1 && e->op == EXPR_MUL) ||
-             (e->left.data.int_val == 0 && e->op == EXPR_ADD) ||
-             (e->left.data.int_val == -1 && e->op == EXPR_AND) ||
-             (e->left.data.int_val == 0 && e->op == EXPR_OR))) {
+    if (e->left.type == EXPR_INT &&
+            ((intnum_is_pos1(e->left.data.intn) && e->op == EXPR_MUL) ||
+             (intnum_is_zero(e->left.data.intn) && e->op == EXPR_ADD) ||
+             (intnum_is_neg1(e->left.data.intn) && e->op == EXPR_AND) ||
+             (intnum_is_zero(e->left.data.intn) && e->op == EXPR_OR))) {
+       intnum_delete(e->left.data.intn);
        e->op = EXPR_IDENT;
        simplified = 1;
     }
     /* and the corresponding x+|-0, x*&/1 */
     else if (e->right.type == EXPR_INT &&
-            ((e->right.data.int_val == 1 && e->op == EXPR_MUL) ||
-             (e->right.data.int_val == 1 && e->op == EXPR_DIV) ||
-             (e->right.data.int_val == 0 && e->op == EXPR_ADD) ||
-             (e->right.data.int_val == 0 && e->op == EXPR_SUB) ||
-             (e->right.data.int_val == -1 && e->op == EXPR_AND) ||
-             (e->right.data.int_val == 0 && e->op == EXPR_OR) ||
-             (e->right.data.int_val == 0 && e->op == EXPR_SHL) ||
-             (e->right.data.int_val == 0 && e->op == EXPR_SHR))) {
+            ((intnum_is_pos1(e->right.data.intn) && e->op == EXPR_MUL) ||
+             (intnum_is_pos1(e->right.data.intn) && e->op == EXPR_DIV) ||
+             (intnum_is_zero(e->right.data.intn) && e->op == EXPR_ADD) ||
+             (intnum_is_zero(e->right.data.intn) && e->op == EXPR_SUB) ||
+             (intnum_is_neg1(e->right.data.intn) && e->op == EXPR_AND) ||
+             (intnum_is_zero(e->right.data.intn) && e->op == EXPR_OR) ||
+             (intnum_is_zero(e->right.data.intn) && e->op == EXPR_SHL) ||
+             (intnum_is_zero(e->right.data.intn) && e->op == EXPR_SHR))) {
+       intnum_delete(e->right.data.intn);
        e->op = EXPR_IDENT;
        e->right.type = e->left.type;
        memcpy(&e->right, &e->left, sizeof(ExprItem));
        simplified = 1;
+    } else if ((e->left.type == EXPR_INT || e->left.type == EXPR_NONE) &&
+       e->right.type == EXPR_INT && e->op != EXPR_IDENT) {
+       intnum_calc(e->left.data.intn, e->op, e->right.data.intn);
+       intnum_delete(e->right.data.intn);
+       e->right.data.intn = e->left.data.intn;
+       e->op = EXPR_IDENT;
+       simplified = 1;
     }
 
     return simplified;
 }
 
-int
-expr_get_value(expr *e, unsigned long *retval)
-{
-    while (!(e->op == EXPR_IDENT && e->right.type == EXPR_INT)
-          && expr_simplify(e)) ;
-
-    if (e->op == EXPR_IDENT && e->right.type == EXPR_INT) {
-       *retval = e->right.data.int_val;
-       return 1;
-    } else
-       return 0;
-}
-
 void
 expr_print(expr *e)
 {
@@ -336,7 +252,7 @@ expr_print(expr *e)
                printf(")");
                break;
            case EXPR_INT:
-               printf("%lu", e->left.data.int_val);
+               intnum_print(e->left.data.intn);
                break;
            case EXPR_FLOAT:
                floatnum_print(e->left.data.flt);
@@ -358,9 +274,15 @@ expr_print(expr *e)
        case EXPR_DIV:
            printf("/");
            break;
+       case EXPR_SIGNDIV:
+           printf("//");
+           break;
        case EXPR_MOD:
            printf("%%");
            break;
+       case EXPR_SIGNMOD:
+           printf("%%%%");
+           break;
        case EXPR_NEG:
            printf("-");
            break;
@@ -422,7 +344,7 @@ expr_print(expr *e)
            printf(")");
            break;
        case EXPR_INT:
-           printf("%lu", e->right.data.int_val);
+           intnum_print(e->right.data.intn);
            break;
        case EXPR_FLOAT:
            floatnum_print(e->right.data.flt);
index 96620a1d469383e4d461dd023d87fca9eba7af27..24bf0b203ecdfe135c72183f234ad2b82dd6e5a3 100644 (file)
@@ -37,6 +37,7 @@
 
 #include "globals.h"
 #include "errwarn.h"
+#include "intnum.h"
 #include "floatnum.h"
 #include "expr.h"
 
@@ -73,11 +74,10 @@ struct immval {
 struct dataval {
     STAILQ_ENTRY(dataval) link;
 
-    enum { DV_EMPTY, DV_EXPR, DV_FLOAT, DV_STRING } type;
+    enum { DV_EMPTY, DV_EXPR, DV_STRING } type;
 
     union {
        expr *expn;
-       floatnum *flt;
        char *str_val;
     } data;
 };
@@ -229,7 +229,7 @@ immval_new_int(unsigned long int_val)
 {
     immval *im = xmalloc(sizeof(immval));
 
-    im->val = expr_new_ident(ExprInt(int_val));
+    im->val = expr_new_ident(ExprInt(intnum_new_int(int_val)));
 
     if ((int_val & 0xFF) == int_val)
        im->len = 1;
@@ -249,7 +249,7 @@ immval_new_expr(expr *expr_ptr)
     immval *im = xmalloc(sizeof(immval));
 
     im->val = expr_ptr;
-
+    im->len = 0;
     im->isneg = 0;
 
     return im;
@@ -486,46 +486,7 @@ bytecode_new_jmprel(targetval     *target,
 bytecode *
 bytecode_new_data(datavalhead *datahead, unsigned long size)
 {
-    bytecode *bc;
-    dataval *cur;
-
-    /* First check to see if all the data elements are valid for the size
-     * being set.
-     * Validity table:
-     *  db (1)  -> expr, string
-     *  dw (2)  -> expr, string
-     *  dd (4)  -> expr, float, string
-     *  dq (8)  -> expr, float, string
-     *  dt (10) -> float, string
-     *
-     * Once we calculate expr we'll have to validate it against the size
-     * and warn/error appropriately (symbol constants versus labels:
-     * constants (equ's) should always be legal, but labels should raise
-     * warnings when used in db or dq context at the minimum).
-     */
-    STAILQ_FOREACH(cur, datahead, link) {
-       switch (cur->type) {
-           case DV_EMPTY:
-           case DV_STRING:
-               /* string is valid in every size */
-               break;
-           case DV_FLOAT:
-               if (size == 1)
-                   Error(_("floating-point constant encountered in `%s'"),
-                         "DB");
-               else if (size == 2)
-                   Error(_("floating-point constant encountered in `%s'"),
-                         "DW");
-               break;
-           case DV_EXPR:
-               if (size == 10)
-                   Error(_("non-floating-point value encountered in `%s'"),
-                         "DT");
-               break;
-       }
-    }
-
-    bc = bytecode_new_common();
+    bytecode *bc = bytecode_new_common();
 
     bc->type = BC_DATA;
 
@@ -570,14 +531,14 @@ bytecode_print(bytecode *bc)
                printf("\n Disp=");
                expr_print(bc->data.insn.ea->disp);
                printf("\n");
-               printf(" Len=%u SegmentOv=%2x\n",
+               printf(" Len=%u SegmentOv=%02x\n",
                       (unsigned int)bc->data.insn.ea->len,
                       (unsigned int)bc->data.insn.ea->segment);
-               printf(" ModRM=%2x ValidRM=%u NeedRM=%u\n",
+               printf(" ModRM=%02x ValidRM=%u NeedRM=%u\n",
                       (unsigned int)bc->data.insn.ea->modrm,
                       (unsigned int)bc->data.insn.ea->valid_modrm,
                       (unsigned int)bc->data.insn.ea->need_modrm);
-               printf(" SIB=%2x ValidSIB=%u NeedSIB=%u\n",
+               printf(" SIB=%02x ValidSIB=%u NeedSIB=%u\n",
                       (unsigned int)bc->data.insn.ea->sib,
                       (unsigned int)bc->data.insn.ea->valid_sib,
                       (unsigned int)bc->data.insn.ea->need_sib);
@@ -595,16 +556,17 @@ bytecode_print(bytecode *bc)
                printf(" FLen=%u, FSign=%u\n",
                       (unsigned int)bc->data.insn.imm->f_len,
                       (unsigned int)bc->data.insn.imm->f_sign);
-               printf("Opcode: %2x %2x %2x OpLen=%u\n",
-                      (unsigned int)bc->data.insn.opcode[0],
-                      (unsigned int)bc->data.insn.opcode[1],
-                      (unsigned int)bc->data.insn.opcode[2],
-                      (unsigned int)bc->data.insn.opcode_len);
-               printf("AddrSize=%u OperSize=%u LockRepPre=%2x\n",
-                      (unsigned int)bc->data.insn.addrsize,
-                      (unsigned int)bc->data.insn.opersize,
-                      (unsigned int)bc->data.insn.lockrep_pre);
            }
+           printf("Opcode: %02x %02x %02x OpLen=%u\n",
+                  (unsigned int)bc->data.insn.opcode[0],
+                  (unsigned int)bc->data.insn.opcode[1],
+                  (unsigned int)bc->data.insn.opcode[2],
+                  (unsigned int)bc->data.insn.opcode_len);
+           printf("AddrSize=%u OperSize=%u LockRepPre=%02x ShiftOp=%u\n",
+                  (unsigned int)bc->data.insn.addrsize,
+                  (unsigned int)bc->data.insn.opersize,
+                  (unsigned int)bc->data.insn.lockrep_pre,
+                  (unsigned int)bc->data.insn.shift_op);
            break;
        case BC_JMPREL:
            printf("_Relative Jump_\n");
@@ -614,7 +576,7 @@ bytecode_print(bytecode *bc)
            if (!bc->data.jmprel.shortop.opcode_len == 0)
                printf(" None\n");
            else
-               printf(" Opcode: %2x %2x %2x OpLen=%u\n",
+               printf(" Opcode: %02x %02x %02x OpLen=%u\n",
                       (unsigned int)bc->data.jmprel.shortop.opcode[0],
                       (unsigned int)bc->data.jmprel.shortop.opcode[1],
                       (unsigned int)bc->data.jmprel.shortop.opcode[2],
@@ -622,7 +584,7 @@ bytecode_print(bytecode *bc)
            if (!bc->data.jmprel.nearop.opcode_len == 0)
                printf(" None\n");
            else
-               printf(" Opcode: %2x %2x %2x OpLen=%u\n",
+               printf(" Opcode: %02x %02x %02x OpLen=%u\n",
                       (unsigned int)bc->data.jmprel.nearop.opcode[0],
                       (unsigned int)bc->data.jmprel.nearop.opcode[1],
                       (unsigned int)bc->data.jmprel.nearop.opcode[2],
@@ -648,7 +610,7 @@ bytecode_print(bytecode *bc)
                    printf("UNKNOWN!!");
                    break;
            }
-           printf("\nAddrSize=%u OperSize=%u LockRepPre=%2x\n",
+           printf("\nAddrSize=%u OperSize=%u LockRepPre=%02x\n",
                   (unsigned int)bc->data.jmprel.addrsize,
                   (unsigned int)bc->data.jmprel.opersize,
                   (unsigned int)bc->data.jmprel.lockrep_pre);
@@ -690,24 +652,24 @@ bytecodes_append(bytecodehead *headp, bytecode *bc)
     return (bytecode *)NULL;
 }
 
-dataval *
-dataval_new_expr(expr *expn)
+void
+bytecodes_print(const bytecodehead *headp)
 {
-    dataval *retval = xmalloc(sizeof(dataval));
-
-    retval->type = DV_EXPR;
-    retval->data.expn = expn;
+    bytecode *cur;
 
-    return retval;
+    STAILQ_FOREACH(cur, headp, link) {
+       printf("---Next Bytecode---\n");
+       bytecode_print(cur);
+    }
 }
 
 dataval *
-dataval_new_float(floatnum *flt)
+dataval_new_expr(expr *expn)
 {
     dataval *retval = xmalloc(sizeof(dataval));
 
-    retval->type = DV_FLOAT;
-    retval->data.flt = flt;
+    retval->type = DV_EXPR;
+    retval->data.expn = expn;
 
     return retval;
 }
@@ -748,11 +710,6 @@ dataval_print(datavalhead *head)
                expr_print(cur->data.expn);
                printf("\n");
                break;
-           case DV_FLOAT:
-               printf(" Float=");
-               floatnum_print(cur->data.flt);
-               printf("\n");
-               break;
            case DV_STRING:
                printf(" String=%s\n", cur->data.str_val);
                break;
index 32ffa963b778617aad9db2ff928d152aff834a88..be485e4f655310bec37a47b6d7f60692910410b7 100644 (file)
@@ -129,6 +129,8 @@ void bytecode_print(bytecode *bc);
  */
 bytecode *bytecodes_append(bytecodehead *headp, bytecode *bc);
 
+void bytecodes_print(const bytecodehead *headp);
+
 dataval *dataval_new_expr(expr *expn);
 dataval *dataval_new_float(floatnum *flt);
 dataval *dataval_new_string(char *str_val);
index 911fe47dd75f1ae4e494f5cac1889ad456a607d5..252065f738b874426ff4d93aa996c0a79ef8b433 100644 (file)
 #define N_(String)     (String)
 #endif
 
+#include "bitvect.h"
+
 #include "globals.h"
 #include "errwarn.h"
+#include "intnum.h"
 #include "floatnum.h"
 #include "expr.h"
 #include "symrec.h"
@@ -61,7 +64,7 @@ struct ExprItem {
     union {
        symrec *sym;
        expr *expn;
-       unsigned long int_val;
+       intnum *intn;
        floatnum *flt;
     } data;
 };
@@ -69,6 +72,8 @@ struct ExprItem {
 struct expr {
     ExprItem left, right;
     ExprOp op;
+    char *filename;
+    unsigned long line;
 };
 
 /* allocate a new expression node, with children as defined.
@@ -93,6 +98,10 @@ expr_new(ExprItem *left, ExprOp op, ExprItem *right)
        InternalError(__LINE__, __FILE__,
                      _("Right side of expression must exist"));
     }
+
+    ptr->filename = xstrdup(in_filename);
+    ptr->line = line_number;
+
     return ptr;
 }
 
@@ -116,11 +125,11 @@ ExprExpr(expr *x)
 }
 
 ExprItem *
-ExprInt(unsigned long i)
+ExprInt(intnum *i)
 {
     ExprItem *e = xmalloc(sizeof(ExprItem));
     e->type = EXPR_INT;
-    e->data.int_val = i;
+    e->data.intn = i;
     return e;
 }
 
@@ -138,7 +147,7 @@ int
 expr_simplify(expr *e)
 {
     int simplified = 0;
-    unsigned long int_val;
+    ExprItem tmp;
 
     /* try to simplify the left side */
     if (e->left.type == EXPR_EXPR) {
@@ -150,14 +159,14 @@ expr_simplify(expr *e)
         * pull it up into the current node */
        while (e->left.type == EXPR_EXPR &&
               e->left.data.expn->op == EXPR_IDENT) {
-           ExprItem tmp;
-           e->left.type = e->left.data.expn->right.type;
            memcpy(&tmp, &(e->left.data.expn->right), sizeof(ExprItem));
            free(e->left.data.expn);
-           memcpy(&(e->left.data.int_val), &tmp, sizeof(ExprItem));
+           memcpy(&e->left, &tmp, sizeof(ExprItem));
            simplified = 1;
        }
-    } else if (e->left.type == EXPR_SYM) {
+    }
+#if 0
+    else if (e->left.type == EXPR_SYM) {
        /* try to get value of symbol */
        if (symrec_get_int_value(e->left.data.sym, &int_val, 0)) {
            e->left.type = EXPR_INT;
@@ -166,6 +175,7 @@ expr_simplify(expr *e)
            simplified = 1;
        }
     }
+#endif
 
     /* ditto on the right */
     if (e->right.type == EXPR_EXPR) {
@@ -174,14 +184,14 @@ expr_simplify(expr *e)
 
        while (e->right.type == EXPR_EXPR &&
               e->right.data.expn->op == EXPR_IDENT) {
-           ExprItem tmp;
-           e->right.type = e->right.data.expn->right.type;
            memcpy(&tmp, &(e->right.data.expn->right), sizeof(ExprItem));
            free(e->right.data.expn);
-           memcpy(&(e->right.data.int_val), &tmp, sizeof(ExprItem));
+           memcpy(&e->right, &tmp, sizeof(ExprItem));
            simplified = 1;
        }
-    } else if (e->right.type == EXPR_SYM) {
+    }
+#if 0
+    else if (e->right.type == EXPR_SYM) {
        if (symrec_get_int_value(e->right.data.sym, &int_val, 0)) {
            e->right.type = EXPR_INT;
            /* don't try to free the symrec here. */
@@ -189,139 +199,45 @@ expr_simplify(expr *e)
            simplified = 1;
        }
     }
-
-    if ((e->left.type == EXPR_INT || e->left.type == EXPR_NONE) &&
-       e->right.type == EXPR_INT && e->op != EXPR_IDENT) {
-       switch (e->op) {
-           case EXPR_ADD:
-               e->right.data.int_val = e->left.data.int_val +
-                                       e->right.data.int_val;
-               break;
-           case EXPR_SUB:
-               e->right.data.int_val = e->left.data.int_val -
-                                       e->right.data.int_val;
-               break;
-           case EXPR_MUL:
-               e->right.data.int_val = e->left.data.int_val *
-                                       e->right.data.int_val;
-               break;
-           case EXPR_DIV:
-               e->right.data.int_val = e->left.data.int_val /
-                                       e->right.data.int_val;
-               break;
-           case EXPR_MOD:
-               e->right.data.int_val = e->left.data.int_val %
-                                       e->right.data.int_val;
-               break;
-           case EXPR_NEG:
-               e->right.data.int_val = -(e->right.data.int_val);
-               break;
-           case EXPR_NOT:
-               e->right.data.int_val = ~(e->right.data.int_val);
-               break;
-           case EXPR_OR:
-               e->right.data.int_val = e->left.data.int_val |
-                                       e->right.data.int_val;
-               break;
-           case EXPR_AND:
-               e->right.data.int_val = e->left.data.int_val &
-                                       e->right.data.int_val;
-               break;
-           case EXPR_XOR:
-               e->right.data.int_val = e->left.data.int_val ^
-                                       e->right.data.int_val;
-               break;
-           case EXPR_SHL:
-               e->right.data.int_val = e->right.data.int_val <<
-                                       e->left.data.int_val;
-               break;
-           case EXPR_SHR:
-               e->right.data.int_val = e->right.data.int_val >>
-                                       e->left.data.int_val;
-               break;
-           case EXPR_LOR:
-               e->right.data.int_val = e->left.data.int_val ||
-                                       e->right.data.int_val;
-               break;
-           case EXPR_LAND:
-               e->right.data.int_val = e->left.data.int_val &&
-                                       e->right.data.int_val;
-               break;
-           case EXPR_LNOT:
-               e->right.data.int_val = !e->right.data.int_val;
-               break;
-           case EXPR_EQ:
-               e->right.data.int_val = e->right.data.int_val ==
-                                       e->left.data.int_val;
-               break;
-           case EXPR_LT:
-               e->right.data.int_val = e->right.data.int_val <
-                                       e->left.data.int_val;
-               break;
-           case EXPR_GT:
-               e->right.data.int_val = e->right.data.int_val >
-                                       e->left.data.int_val;
-               break;
-           case EXPR_LE:
-               e->right.data.int_val = e->right.data.int_val <=
-                                       e->left.data.int_val;
-               break;
-           case EXPR_GE:
-               e->right.data.int_val = e->right.data.int_val >=
-                                       e->left.data.int_val;
-               break;
-           case EXPR_NE:
-               e->right.data.int_val = e->right.data.int_val !=
-                                       e->left.data.int_val;
-               break;
-           case EXPR_IDENT:
-               break;
-       }
-       e->op = EXPR_IDENT;
-       simplified = 1;
-    }
+#endif
 
     /* catch simple identities like 0+x, 1*x, etc., for x not a num */
-    else if (e->left.type == EXPR_INT &&
-            ((e->left.data.int_val == 1 && e->op == EXPR_MUL) ||
-             (e->left.data.int_val == 0 && e->op == EXPR_ADD) ||
-             (e->left.data.int_val == -1 && e->op == EXPR_AND) ||
-             (e->left.data.int_val == 0 && e->op == EXPR_OR))) {
+    if (e->left.type == EXPR_INT &&
+            ((intnum_is_pos1(e->left.data.intn) && e->op == EXPR_MUL) ||
+             (intnum_is_zero(e->left.data.intn) && e->op == EXPR_ADD) ||
+             (intnum_is_neg1(e->left.data.intn) && e->op == EXPR_AND) ||
+             (intnum_is_zero(e->left.data.intn) && e->op == EXPR_OR))) {
+       intnum_delete(e->left.data.intn);
        e->op = EXPR_IDENT;
        simplified = 1;
     }
     /* and the corresponding x+|-0, x*&/1 */
     else if (e->right.type == EXPR_INT &&
-            ((e->right.data.int_val == 1 && e->op == EXPR_MUL) ||
-             (e->right.data.int_val == 1 && e->op == EXPR_DIV) ||
-             (e->right.data.int_val == 0 && e->op == EXPR_ADD) ||
-             (e->right.data.int_val == 0 && e->op == EXPR_SUB) ||
-             (e->right.data.int_val == -1 && e->op == EXPR_AND) ||
-             (e->right.data.int_val == 0 && e->op == EXPR_OR) ||
-             (e->right.data.int_val == 0 && e->op == EXPR_SHL) ||
-             (e->right.data.int_val == 0 && e->op == EXPR_SHR))) {
+            ((intnum_is_pos1(e->right.data.intn) && e->op == EXPR_MUL) ||
+             (intnum_is_pos1(e->right.data.intn) && e->op == EXPR_DIV) ||
+             (intnum_is_zero(e->right.data.intn) && e->op == EXPR_ADD) ||
+             (intnum_is_zero(e->right.data.intn) && e->op == EXPR_SUB) ||
+             (intnum_is_neg1(e->right.data.intn) && e->op == EXPR_AND) ||
+             (intnum_is_zero(e->right.data.intn) && e->op == EXPR_OR) ||
+             (intnum_is_zero(e->right.data.intn) && e->op == EXPR_SHL) ||
+             (intnum_is_zero(e->right.data.intn) && e->op == EXPR_SHR))) {
+       intnum_delete(e->right.data.intn);
        e->op = EXPR_IDENT;
        e->right.type = e->left.type;
        memcpy(&e->right, &e->left, sizeof(ExprItem));
        simplified = 1;
+    } else if ((e->left.type == EXPR_INT || e->left.type == EXPR_NONE) &&
+       e->right.type == EXPR_INT && e->op != EXPR_IDENT) {
+       intnum_calc(e->left.data.intn, e->op, e->right.data.intn);
+       intnum_delete(e->right.data.intn);
+       e->right.data.intn = e->left.data.intn;
+       e->op = EXPR_IDENT;
+       simplified = 1;
     }
 
     return simplified;
 }
 
-int
-expr_get_value(expr *e, unsigned long *retval)
-{
-    while (!(e->op == EXPR_IDENT && e->right.type == EXPR_INT)
-          && expr_simplify(e)) ;
-
-    if (e->op == EXPR_IDENT && e->right.type == EXPR_INT) {
-       *retval = e->right.data.int_val;
-       return 1;
-    } else
-       return 0;
-}
-
 void
 expr_print(expr *e)
 {
@@ -336,7 +252,7 @@ expr_print(expr *e)
                printf(")");
                break;
            case EXPR_INT:
-               printf("%lu", e->left.data.int_val);
+               intnum_print(e->left.data.intn);
                break;
            case EXPR_FLOAT:
                floatnum_print(e->left.data.flt);
@@ -358,9 +274,15 @@ expr_print(expr *e)
        case EXPR_DIV:
            printf("/");
            break;
+       case EXPR_SIGNDIV:
+           printf("//");
+           break;
        case EXPR_MOD:
            printf("%%");
            break;
+       case EXPR_SIGNMOD:
+           printf("%%%%");
+           break;
        case EXPR_NEG:
            printf("-");
            break;
@@ -422,7 +344,7 @@ expr_print(expr *e)
            printf(")");
            break;
        case EXPR_INT:
-           printf("%lu", e->right.data.int_val);
+           intnum_print(e->right.data.intn);
            break;
        case EXPR_FLOAT:
            floatnum_print(e->right.data.flt);
index 25a0bb48f92f234643a3f4a775b6b10ce8483cf2..8adad2db4e546b7facae7607fa85ec09fb4f8f20 100644 (file)
@@ -32,12 +32,21 @@ typedef struct symrec symrec;
 typedef struct floatnum floatnum;
 #endif
 
+#ifndef YASM_INTNUM
+#define YASM_INTNUM
+typedef struct intnum intnum;
+#endif
+
+#ifndef YASM_EXPROP
+#define YASM_EXPROP
 typedef enum {
     EXPR_ADD,
     EXPR_SUB,
     EXPR_MUL,
     EXPR_DIV,
+    EXPR_SIGNDIV,
     EXPR_MOD,
+    EXPR_SIGNMOD,
     EXPR_NEG,
     EXPR_NOT,
     EXPR_OR,
@@ -56,6 +65,7 @@ typedef enum {
     EXPR_NE,
     EXPR_IDENT                 /* if right is IDENT, then the entire expr is just a num */
 } ExprOp;
+#endif
 
 typedef struct ExprItem ExprItem;
 
@@ -68,7 +78,7 @@ expr *expr_new(ExprItem *, ExprOp, ExprItem *);
 
 ExprItem *ExprSym(symrec *);
 ExprItem *ExprExpr(expr *);
-ExprItem *ExprInt(unsigned long);
+ExprItem *ExprInt(intnum *);
 ExprItem *ExprFloat(floatnum *);
 
 #define expr_new_tree(l,o,r) \
@@ -81,7 +91,4 @@ ExprItem *ExprFloat(floatnum *);
 int expr_simplify(expr *);
 void expr_print(expr *);
 
-/* get the value if possible.  return value is IF POSSIBLE, not the val */
-int expr_get_value(expr *, unsigned long *);
-
 #endif
index d2e143ffe540e9d2a6352e7820abbbb70bfc9f42..30ae74141239ad2fca16a4382a90992299cb63b6 100644 (file)
@@ -498,20 +498,28 @@ floatnum_delete(floatnum *flt)
     free(flt);
 }
 
+void
+floatnum_calc(floatnum *acc, ExprOp op, floatnum *operand)
+{
+    if (op != EXPR_NEG)
+       Error(_("Unsupported floating-point arithmetic operation"));
+    else
+       acc->sign ^= 1;
+}
+
 int
 floatnum_get_int(unsigned long *ret_val, const floatnum *flt)
 {
     unsigned char t[4];
 
-    if (floatnum_get_single(t, flt))
+    if (floatnum_get_sized(t, flt, 4))
        return 1;
 
     LOAD_LONG(*ret_val, &t[0]);
     return 0;
 }
 
-/* Function used by single, double, and extended conversion routines to actually
- * perform the conversion.
+/* Function used by conversion routines to actually perform the conversion.
  *
  * ptr -> the array to return the little-endian floating point value into.
  * flt -> the floating point value to convert.
@@ -614,14 +622,8 @@ floatnum_get_common(unsigned char *ptr, const floatnum *flt, int byte_size,
  * e = bias 127 exponent
  * s = sign bit
  * m = mantissa bits, bit 23 is an implied one bit.
- */
-int
-floatnum_get_single(unsigned char *ptr, const floatnum *flt)
-{
-    return floatnum_get_common(ptr, flt, 4, 23, 1, 8);
-}
-
-/* IEEE-754 (Intel) "double precision" format:
+ *
+ * IEEE-754 (Intel) "double precision" format:
  * 64 bits:
  * bit 63       bit 51                                               bit 0
  * |            |                                                        |
@@ -630,14 +632,8 @@ floatnum_get_single(unsigned char *ptr, const floatnum *flt)
  * e = bias 1023 exponent.
  * s = sign bit.
  * m = mantissa bits.  Bit 52 is an implied one bit.
- */
-int
-floatnum_get_double(unsigned char *ptr, const floatnum *flt)
-{
-    return floatnum_get_common(ptr, flt, 8, 52, 1, 11);
-}
-
-/* IEEE-754 (Intel) "extended precision" format:
+ *
+ * IEEE-754 (Intel) "extended precision" format:
  * 80 bits:
  * bit 79            bit 63                           bit 0
  * |                 |                                    |
@@ -648,9 +644,34 @@ floatnum_get_double(unsigned char *ptr, const floatnum *flt)
  * s = sign (for mantissa)
  */
 int
-floatnum_get_extended(unsigned char *ptr, const floatnum *flt)
+floatnum_get_sized(unsigned char *ptr, const floatnum *flt, size_t size)
 {
-    return floatnum_get_common(ptr, flt, 10, 64, 0, 15);
+    switch (size) {
+       case 4:
+           return floatnum_get_common(ptr, flt, 4, 23, 1, 8);
+       case 8:
+           return floatnum_get_common(ptr, flt, 8, 52, 1, 11);
+       case 10:
+           return floatnum_get_common(ptr, flt, 10, 64, 0, 15);
+       default:
+           InternalError(__LINE__, __FILE__,
+                         _("Invalid float conversion size"));
+           return 1;       /* never reached, but silence GCC warning */
+    }
+}
+
+/* 1 if the size is valid, 0 if it isn't */
+int
+floatnum_check_size(const floatnum *flt, size_t size)
+{
+    switch (size) {
+       case 4:
+       case 8:
+       case 10:
+           return 1;
+       default:
+           return 0;
+    }
 }
 
 void
@@ -666,19 +687,19 @@ floatnum_print(const floatnum *flt)
     free(str);
 
     /* 32-bit (single precision) format */
-    printf("32-bit: %d: ", floatnum_get_single(out, flt));
+    printf("32-bit: %d: ", floatnum_get_sized(out, flt, 4));
     for (i=0; i<4; i++)
        printf("%02x ", out[i]);
     printf("\n");
 
     /* 64-bit (double precision) format */
-    printf("64-bit: %d: ", floatnum_get_double(out, flt));
+    printf("64-bit: %d: ", floatnum_get_sized(out, flt, 8));
     for (i=0; i<8; i++)
        printf("%02x ", out[i]);
     printf("\n");
 
     /* 80-bit (extended precision) format */
-    printf("80-bit: %d: ", floatnum_get_extended(out, flt));
+    printf("80-bit: %d: ", floatnum_get_sized(out, flt, 10));
     for (i=0; i<10; i++)
        printf("%02x ", out[i]);
     printf("\n");
index 612922497468264c37d61426e37f69f9aff908c8..4963e79a536ea3f4a33b618d3a99963730fefdb9 100644 (file)
 #ifndef YASM_FLOATNUM_H
 #define YASM_FLOATNUM_H
 
+#ifndef YASM_EXPROP
+#define YASM_EXPROP
+typedef enum {
+    EXPR_ADD,
+    EXPR_SUB,
+    EXPR_MUL,
+    EXPR_DIV,
+    EXPR_SIGNDIV,
+    EXPR_MOD,
+    EXPR_SIGNMOD,
+    EXPR_NEG,
+    EXPR_NOT,
+    EXPR_OR,
+    EXPR_AND,
+    EXPR_XOR,
+    EXPR_SHL,
+    EXPR_SHR,
+    EXPR_LOR,
+    EXPR_LAND,
+    EXPR_LNOT,
+    EXPR_LT,
+    EXPR_GT,
+    EXPR_EQ,
+    EXPR_LE,
+    EXPR_GE,
+    EXPR_NE,
+    EXPR_IDENT /* if right is IDENT, then the entire expr is just a num */
+} ExprOp;
+#endif
+
 #ifndef YASM_FLOATNUM
 #define YASM_FLOATNUM
 typedef struct floatnum floatnum;
@@ -32,7 +62,12 @@ typedef struct floatnum floatnum;
 floatnum *floatnum_new(const char *str);
 void floatnum_delete(floatnum *flt);
 
-/* The get functions return nonzero if flt can't fit into that size format. */
+/* calculation function: acc = acc op operand */
+void floatnum_calc(floatnum *acc, ExprOp op, floatnum *operand);
+
+/* The get functions return nonzero if flt can't fit into that size format:
+ * -1 if underflow occurred, 1 if overflow occurred.
+ */
 
 /* Essentially a convert to single-precision and return as 32-bit value.
  * The 32-bit value is a "standard" C value (eg, of unknown endian).
@@ -42,9 +77,13 @@ int floatnum_get_int(unsigned long *ret_val, const floatnum *flt);
 /* ptr will point to the Intel-format little-endian byte string after a
  * successful call (eg, [0] should be the first byte output to the file).
  */
-int floatnum_get_single(unsigned char *ptr, const floatnum *flt);
-int floatnum_get_double(unsigned char *ptr, const floatnum *flt);
-int floatnum_get_extended(unsigned char *ptr, const floatnum *flt);
+int floatnum_get_sized(unsigned char *ptr, const floatnum *flt, size_t size);
+
+/* Basic check to see if size is even valid for flt conversion (doesn't
+ * actually check for underflow/overflow but rather checks for size=4,8,10).
+ * Returns 1 if valid, 0 if not.
+ */
+int floatnum_check_size(const floatnum *flt, size_t size);
 
 void floatnum_print(const floatnum *flt);
 
diff --git a/src/intnum.c b/src/intnum.c
new file mode 100644 (file)
index 0000000..05f5303
--- /dev/null
@@ -0,0 +1,542 @@
+/* $IdPath$
+ * Integer number functions.
+ *
+ *  Copyright (C) 2001  Peter Johnson
+ *
+ *  This file is part of YASM.
+ *
+ *  YASM is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  YASM is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include "util.h"
+
+#include <stdio.h>
+#include <ctype.h>
+
+#ifdef STDC_HEADERS
+# include <stdlib.h>
+# include <string.h>
+#endif
+
+#include <libintl.h>
+#define _(String)      gettext(String)
+
+#include "bitvect.h"
+#include "file.h"
+
+#include "errwarn.h"
+#include "intnum.h"
+
+RCSID("$IdPath$");
+
+#define BITVECT_ALLOC_SIZE     80
+
+struct intnum {
+    union val {
+       unsigned long ul;       /* integer value (for integers <=32 bits) */
+       intptr bv;              /* bit vector (for integers >32 bits) */
+    } val;
+    enum { INTNUM_UL, INTNUM_BV } type;
+    unsigned char origsize;    /* original (parsed) size, in bits */
+};
+
+intnum *
+intnum_new_dec(char *str)
+{
+    intnum *intn = xmalloc(sizeof(intnum));
+    wordptr bv;
+
+    intn->origsize = 0;            /* no reliable way to figure this out */
+
+    bv = BitVector_Create(BITVECT_ALLOC_SIZE, FALSE);
+    if (BitVector_from_Dec(bv, (unsigned char *)str) == ErrCode_Ovfl)
+       Warning(_("Numeric constant too large for internal format"));
+    if (Set_Max(bv) < 32) {
+       intn->type = INTNUM_UL;
+       intn->val.ul = BitVector_Chunk_Read(bv, 32, 0);
+       BitVector_Destroy(bv);
+    } else {
+       intn->type = INTNUM_BV;
+       intn->val.bv = bv;
+    }
+
+    return intn;
+}
+
+intnum *
+intnum_new_bin(char *str)
+{
+    intnum *intn = xmalloc(sizeof(intnum));
+    wordptr bv;
+
+    intn->origsize = strlen(str);
+
+    if(intn->origsize > BITVECT_ALLOC_SIZE)
+       Warning(_("Numeric constant too large for internal format"));
+
+    bv = BitVector_Create(BITVECT_ALLOC_SIZE, FALSE);
+    BitVector_from_Bin(bv, (unsigned char *)str);
+    if (Set_Max(bv) < 32) {
+       intn->type = INTNUM_UL;
+       intn->val.ul = BitVector_Chunk_Read(bv, 32, 0);
+       BitVector_Destroy(bv);
+    } else {
+       intn->type = INTNUM_BV;
+       intn->val.bv = bv;
+    }
+
+    return intn;
+}
+
+intnum *
+intnum_new_oct(char *str)
+{
+    intnum *intn = xmalloc(sizeof(intnum));
+    wordptr bv;
+
+    intn->origsize = strlen(str)*3;
+
+    if(intn->origsize > BITVECT_ALLOC_SIZE)
+       Warning(_("Numeric constant too large for internal format"));
+
+    bv = BitVector_Create(BITVECT_ALLOC_SIZE, FALSE);
+    BitVector_from_Oct(bv, (unsigned char *)str);
+    if (Set_Max(bv) < 32) {
+       intn->type = INTNUM_UL;
+       intn->val.ul = BitVector_Chunk_Read(bv, 32, 0);
+       BitVector_Destroy(bv);
+    } else {
+       intn->type = INTNUM_BV;
+       intn->val.bv = bv;
+    }
+
+    return intn;
+}
+
+intnum *
+intnum_new_hex(char *str)
+{
+    intnum *intn = xmalloc(sizeof(intnum));
+    wordptr bv;
+
+    intn->origsize = strlen(str)*4;
+
+    if(intn->origsize > BITVECT_ALLOC_SIZE)
+       Warning(_("Numeric constant too large for internal format"));
+
+    bv = BitVector_Create(BITVECT_ALLOC_SIZE, FALSE);
+    BitVector_from_Hex(bv, (unsigned char *)str);
+    if (Set_Max(bv) < 32) {
+       intn->type = INTNUM_UL;
+       intn->val.ul = BitVector_Chunk_Read(bv, 32, 0);
+       BitVector_Destroy(bv);
+    } else {
+       intn->type = INTNUM_BV;
+       intn->val.bv = bv;
+    }
+
+    return intn;
+}
+
+intnum *
+intnum_new_charconst_nasm(const char *str)
+{
+    intnum *intn = xmalloc(sizeof(intnum));
+    size_t len = strlen(str);
+
+    if (len > 4)
+       Warning(_("character constant too large, ignoring trailing characters"));
+
+    intn->val.ul = 0;
+    intn->type = INTNUM_UL;
+    intn->origsize = len*8;
+
+    switch (len) {
+       case 4:
+           intn->val.ul |= (unsigned long)str[3];
+           intn->val.ul <<= 8;
+       case 3:
+           intn->val.ul |= (unsigned long)str[2];
+           intn->val.ul <<= 8;
+       case 2:
+           intn->val.ul |= (unsigned long)str[1];
+           intn->val.ul <<= 8;
+       case 1:
+           intn->val.ul |= (unsigned long)str[0];
+    }
+
+    return intn;
+}
+
+intnum *
+intnum_new_int(unsigned long i)
+{
+    intnum *intn = xmalloc(sizeof(intnum));
+
+    intn->val.ul = i;
+    intn->type = INTNUM_UL;
+    intn->origsize = 0;
+
+    return intn;
+}
+
+void
+intnum_delete(intnum *intn)
+{
+    if (intn->type == INTNUM_BV)
+       BitVector_Destroy(intn->val.bv);
+    free(intn);
+}
+
+void
+intnum_calc(intnum *acc, ExprOp op, intnum *operand)
+{
+    wordptr result = (wordptr)NULL, op1 = (wordptr)NULL, op2 = (wordptr)NULL;
+    wordptr spare;
+    boolean carry;
+
+    /* upsize to bitvector op if one of two parameters is bitvector already.
+     * BitVector results must be calculated through intermediate storage.
+     */
+    if (acc->type == INTNUM_BV || (operand && operand->type == INTNUM_BV)) {
+       result = BitVector_Create(BITVECT_ALLOC_SIZE, FALSE);
+       spare = BitVector_Create(BITVECT_ALLOC_SIZE, FALSE);
+
+       if (acc->type == INTNUM_BV)
+           op1 = acc->val.bv;
+       else {
+           op1 = BitVector_Create(BITVECT_ALLOC_SIZE, TRUE);
+           BitVector_Chunk_Store(op1, 32, 0, acc->val.ul);
+       }
+
+       if (operand) {
+           if (operand->type == INTNUM_BV)
+               op2 = acc->val.bv;
+           else {
+               op2 = BitVector_Create(BITVECT_ALLOC_SIZE, TRUE);
+               BitVector_Chunk_Store(op2, 32, 0, operand->val.ul);
+           }
+       }
+    }
+
+    if (!operand && op != EXPR_NEG && op != EXPR_NOT && op != EXPR_LNOT)
+       InternalError(__LINE__, __FILE__, _("Operation needs an operand"));
+
+    /* A operation does a bitvector computation if result is allocated. */
+    switch (op) {
+       case EXPR_ADD:
+           if (result)
+               BitVector_add(result, op1, op2, &carry);
+           else
+               acc->val.ul = acc->val.ul + operand->val.ul;
+           break;
+       case EXPR_SUB:
+           if (result)
+               BitVector_sub(result, op1, op2, &carry);
+           else
+               acc->val.ul = acc->val.ul - operand->val.ul;
+           break;
+       case EXPR_MUL:
+           if (result)
+               /* TODO: Make sure result size = op1+op2 */
+               BitVector_Multiply(result, op1, op2);
+           else
+               acc->val.ul = acc->val.ul * operand->val.ul;
+           break;
+       case EXPR_DIV:
+           if (result) {
+               /* TODO: make sure op1 and op2 are unsigned */
+               BitVector_Divide(result, op1, op2, spare);
+           } else
+               acc->val.ul = acc->val.ul / operand->val.ul;
+           break;
+       case EXPR_SIGNDIV:
+           if (result)
+               BitVector_Divide(result, op1, op2, spare);
+           else
+               acc->val.ul = (unsigned long)((signed long)acc->val.ul /
+                                             (signed long)operand->val.ul);
+           break;
+       case EXPR_MOD:
+           if (result) {
+               /* TODO: make sure op1 and op2 are unsigned */
+               BitVector_Divide(spare, op1, op2, result);
+           } else
+               acc->val.ul = acc->val.ul % operand->val.ul;
+           break;
+       case EXPR_SIGNMOD:
+           if (result)
+               BitVector_Divide(spare, op1, op2, result);
+           else
+               acc->val.ul = (unsigned long)((signed long)acc->val.ul %
+                                             (signed long)operand->val.ul);
+           break;
+       case EXPR_NEG:
+           if (result)
+               BitVector_Negate(result, op1);
+           else
+               acc->val.ul = -(acc->val.ul);
+           break;
+       case EXPR_NOT:
+           if (result)
+               Set_Complement(result, op1);
+           else
+               acc->val.ul = ~(acc->val.ul);
+           break;
+       case EXPR_OR:
+           if (result)
+               Set_Union(result, op1, op2);
+           else
+               acc->val.ul = acc->val.ul | operand->val.ul;
+           break;
+       case EXPR_AND:
+           if (result)
+               Set_Intersection(result, op1, op2);
+           else
+               acc->val.ul = acc->val.ul & operand->val.ul;
+           break;
+       case EXPR_XOR:
+           if (result)
+               Set_ExclusiveOr(result, op1, op2);
+           else
+               acc->val.ul = acc->val.ul ^ operand->val.ul;
+           break;
+       case EXPR_SHL:
+           if (result) {
+               if (operand->type == INTNUM_UL) {
+                   BitVector_Copy(result, op1);
+                   BitVector_Move_Left(result, operand->val.ul);
+               } else  /* don't even bother, just zero result */
+                   BitVector_Empty(result);
+           } else
+               acc->val.ul = acc->val.ul << operand->val.ul;
+           break;
+       case EXPR_SHR:
+           if (result) {
+               if (operand->type == INTNUM_UL) {
+                   BitVector_Copy(result, op1);
+                   BitVector_Move_Right(result, operand->val.ul);
+               } else  /* don't even bother, just zero result */
+                   BitVector_Empty(result);
+           } else
+               acc->val.ul = acc->val.ul >> operand->val.ul;
+           break;
+       case EXPR_LOR:
+           if (result) {
+               BitVector_Empty(result);
+               BitVector_LSB(result, !BitVector_is_empty(op1) ||
+                             !BitVector_is_empty(op2));
+           } else
+               acc->val.ul = acc->val.ul || operand->val.ul;
+           break;
+       case EXPR_LAND:
+           if (result) {
+               BitVector_Empty(result);
+               BitVector_LSB(result, !BitVector_is_empty(op1) &&
+                             !BitVector_is_empty(op2));
+           } else
+               acc->val.ul = acc->val.ul && operand->val.ul;
+           break;
+       case EXPR_LNOT:
+           if (result) {
+               BitVector_Empty(result);
+               BitVector_LSB(result, BitVector_is_empty(op1));
+           } else
+               acc->val.ul = !acc->val.ul;
+           break;
+       case EXPR_EQ:
+           if (result) {
+               BitVector_Empty(result);
+               BitVector_LSB(result, BitVector_equal(op1, op2));
+           } else
+               acc->val.ul = acc->val.ul == operand->val.ul;
+           break;
+       case EXPR_LT:
+           if (result) {
+               BitVector_Empty(result);
+               BitVector_LSB(result, BitVector_Lexicompare(op1, op2) < 0);
+           } else
+               acc->val.ul = acc->val.ul < operand->val.ul;
+           break;
+       case EXPR_GT:
+           if (result) {
+               BitVector_Empty(result);
+               BitVector_LSB(result, BitVector_Lexicompare(op1, op2) > 0);
+           } else
+               acc->val.ul = acc->val.ul > operand->val.ul;
+           break;
+       case EXPR_LE:
+           if (result) {
+               BitVector_Empty(result);
+               BitVector_LSB(result, BitVector_Lexicompare(op1, op2) <= 0);
+           } else
+               acc->val.ul = acc->val.ul <= operand->val.ul;
+           break;
+       case EXPR_GE:
+           if (result) {
+               BitVector_Empty(result);
+               BitVector_LSB(result, BitVector_Lexicompare(op1, op2) >= 0);
+           } else
+               acc->val.ul = acc->val.ul >= operand->val.ul;
+           break;
+       case EXPR_NE:
+           if (result) {
+               BitVector_Empty(result);
+               BitVector_LSB(result, !BitVector_equal(op1, op2));
+           } else
+               acc->val.ul = acc->val.ul != operand->val.ul;
+           break;
+       case EXPR_IDENT:
+           if (result)
+               BitVector_Copy(result, op1);
+           break;
+    }
+
+    /* If we were doing a bitvector computation... */
+    if (result) {
+       BitVector_Destroy(spare);
+
+       if (op1 && acc->type != INTNUM_BV)
+           BitVector_Destroy(op1);
+       if (op2 && operand && operand->type != INTNUM_BV)
+           BitVector_Destroy(op2);
+
+       /* Try to fit the result into 32 bits if possible */
+       if (Set_Max(result) < 32) {
+           if (acc->type == INTNUM_BV) {
+               BitVector_Destroy(acc->val.bv);
+               acc->type = INTNUM_UL;
+           }
+           acc->val.ul = BitVector_Chunk_Read(result, 32, 0);
+           BitVector_Destroy(result);
+       } else {
+           if (acc->type == INTNUM_BV) {
+               BitVector_Copy(acc->val.bv, result);
+               BitVector_Destroy(result);
+           } else {
+               acc->type = INTNUM_BV;
+               acc->val.bv = result;
+           }
+       }
+    }
+}
+
+int
+intnum_is_zero(intnum *intn)
+{
+    return ((intn->type == INTNUM_UL && intn->val.ul == 0) ||
+           (intn->type == INTNUM_BV && BitVector_is_empty(intn->val.bv)));
+}
+
+int
+intnum_is_pos1(intnum *intn)
+{
+    return ((intn->type == INTNUM_UL && intn->val.ul == 1) ||
+           (intn->type == INTNUM_BV && Set_Max(intn->val.bv) == 0));
+}
+
+int
+intnum_is_neg1(intnum *intn)
+{
+    return ((intn->type == INTNUM_UL && intn->val.ul == -1) ||
+           (intn->type == INTNUM_BV && BitVector_is_full(intn->val.bv)));
+}
+
+void
+intnum_get_int(unsigned long *ret_val, const intnum *intn)
+{
+    switch (intn->type) {
+       case INTNUM_UL:
+           *ret_val = intn->val.ul;
+           break;
+       case INTNUM_BV:
+           *ret_val = BitVector_Chunk_Read(intn->val.bv, 32, 0);
+           break;
+    }
+}
+
+void
+intnum_get_sized(unsigned char *ptr, const intnum *intn, size_t size)
+{
+    unsigned long ul;
+    unsigned char *buf;
+    unsigned int len;
+
+    switch (intn->type) {
+       case INTNUM_UL:
+           ul = intn->val.ul;
+           while (size-- > 0) {
+               WRITE_BYTE(ptr, ul);
+               if (ul != 0)
+                   ul >>= 8;
+           }
+           break;
+       case INTNUM_BV:
+           buf = BitVector_Block_Read(intn->val.bv, &len);
+           if (len < size)
+               InternalError(__LINE__, __FILE__,
+                             _("Invalid size specified (too large)"));
+           memcpy(ptr, buf, size);
+           free(buf);
+           break;
+    }
+}
+
+/* Return 1 if okay size, 0 if not */
+int
+intnum_check_size(const intnum *intn, size_t size)
+{
+    switch (intn->type) {
+       case INTNUM_UL:
+           if (size >= 4)
+               return 1;
+           switch (size) {
+               case 3:
+                   return ((intn->val.ul & 0x00FFFFFF) == intn->val.ul);
+               case 2:
+                   return ((intn->val.ul & 0x0000FFFF) == intn->val.ul);
+               case 1:
+                   return ((intn->val.ul & 0x000000FF) == intn->val.ul);
+           }
+           break;
+       case INTNUM_BV:
+           if (size >= 10)
+               return 1;
+           else
+               return (Set_Max(intn->val.bv) < size*8);
+           break;
+    }
+    return 0;
+}
+
+void
+intnum_print(const intnum *intn)
+{
+    unsigned char *s;
+
+    switch (intn->type) {
+       case INTNUM_UL:
+           printf("0x%lx/%u", intn->val.ul, (unsigned int)intn->origsize);
+           break;
+       case INTNUM_BV:
+           s = BitVector_to_Hex(intn->val.bv);
+           printf("0x%s/%u", s, (unsigned int)intn->origsize);
+           free(s);
+           break;
+    }
+}
diff --git a/src/intnum.h b/src/intnum.h
new file mode 100644 (file)
index 0000000..62fe9e2
--- /dev/null
@@ -0,0 +1,96 @@
+/* $IdPath$
+ * Integer number functions header file.
+ *
+ *  Copyright (C) 2001  Peter Johnson
+ *
+ *  This file is part of YASM.
+ *
+ *  YASM is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  YASM is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+#ifndef YASM_INTNUM_H
+#define YASM_INTNUM_H
+
+#ifndef YASM_EXPROP
+#define YASM_EXPROP
+typedef enum {
+    EXPR_ADD,
+    EXPR_SUB,
+    EXPR_MUL,
+    EXPR_DIV,
+    EXPR_SIGNDIV,
+    EXPR_MOD,
+    EXPR_SIGNMOD,
+    EXPR_NEG,
+    EXPR_NOT,
+    EXPR_OR,
+    EXPR_AND,
+    EXPR_XOR,
+    EXPR_SHL,
+    EXPR_SHR,
+    EXPR_LOR,
+    EXPR_LAND,
+    EXPR_LNOT,
+    EXPR_LT,
+    EXPR_GT,
+    EXPR_EQ,
+    EXPR_LE,
+    EXPR_GE,
+    EXPR_NE,
+    EXPR_IDENT /* if right is IDENT, then the entire expr is just a num */
+} ExprOp;
+#endif
+
+#ifndef YASM_INTNUM
+#define YASM_INTNUM
+typedef struct intnum intnum;
+#endif
+
+intnum *intnum_new_dec(char *str);
+intnum *intnum_new_bin(char *str);
+intnum *intnum_new_oct(char *str);
+intnum *intnum_new_hex(char *str);
+/* convert character constant to integer value, using NASM rules */
+intnum *intnum_new_charconst_nasm(const char *str);
+intnum *intnum_new_int(unsigned long i);
+void intnum_delete(intnum *intn);
+
+/* calculation function: acc = acc op operand */
+void intnum_calc(intnum *acc, ExprOp op, intnum *operand);
+
+/* simple value checks (for catching identities and the like) */
+int intnum_is_zero(intnum *acc);
+int intnum_is_pos1(intnum *acc);
+int intnum_is_neg1(intnum *acc);
+
+/* The get functions truncate intn to the size specified; they don't check
+ * for overflow.  Use intnum_check_size() to check for overflow.
+ */
+
+/* Return a 32-bit value in "standard" C format (eg, of unknown endian). */
+void intnum_get_int(unsigned long *ret_val, const intnum *intn);
+
+/* ptr will point to the Intel-format little-endian byte string after
+ * call (eg, [0] should be the first byte output to the file).
+ */
+void intnum_get_sized(unsigned char *ptr, const intnum *intn, size_t size);
+
+/* Check to see if intn will fit without overflow in size bytes.
+ * Returns 1 if it will, 0 if not.
+ */
+int intnum_check_size(const intnum *intn, size_t size);
+
+void intnum_print(const intnum *intn);
+
+#endif
index 8e1e6b1f6851213e49e40c71ecd356e83c93d024..6cad2ab297c7ff13530c99511277d709af5bbee7 100644 (file)
@@ -45,6 +45,7 @@
 #include "globals.h"
 #include "options.h"
 #include "errwarn.h"
+#include "symrec.h"
 
 #include "bytecode.h"
 #include "section.h"
@@ -99,6 +100,8 @@ char help_tail[] = "\n"
 int
 main(int argc, char *argv[])
 {
+    sectionhead *sections;
+
     if (parse_cmdline(argc, argv, options, countof(options, opt_option)))
        return EXIT_FAILURE;
 
@@ -123,11 +126,15 @@ main(int argc, char *argv[])
     /* Get initial BITS setting from object format */
     mode_bits = dbg_objfmt.default_mode_bits;
 
-    nasm_parser.do_parse(&nasm_parser, &dbg_objfmt, in);
+    sections = nasm_parser.do_parse(&nasm_parser, &dbg_objfmt, in);
 
     if (OutputAllErrorWarning() > 0)
        return EXIT_FAILURE;
 
+    sections_print(sections);
+    printf("\n***Symbol Table***\n");
+    symrec_foreach((int (*) (symrec *))symrec_print);
+
     if (in_filename)
        free(in_filename);
     return EXIT_SUCCESS;
index c69c2e66ed7f236fe23eab7bfbc3062f0fbf8529..e44fcf456b57adf1390ff2a82ce62df8ff12afb9 100644 (file)
 #include <libintl.h>
 #define _(String)      gettext(String)
 
+#include "bitvect.h"
+
 #include "globals.h"
 #include "errwarn.h"
+#include "intnum.h"
 #include "floatnum.h"
 #include "expr.h"
 #include "symrec.h"
@@ -51,7 +54,6 @@ RCSID("$IdPath$");
 
 void init_table(void);
 extern int nasm_parser_lex(void);
-static unsigned long ConvertCharConstToInt(char *);
 void nasm_parser_error(const char *);
 
 extern objfmt *nasm_parser_objfmt;
@@ -65,9 +67,11 @@ static bytecode *nasm_parser_temp_bc;
 %}
 
 %union {
-    unsigned long int_val;
+    unsigned int int_info;
     char *str_val;
+    intnum *intn;
     floatnum *flt;
+    symrec *sym;
     unsigned char groupdata[4];
     effaddr *ea;
     expr *exp;
@@ -78,23 +82,24 @@ static bytecode *nasm_parser_temp_bc;
     bytecode *bc;
 }
 
-%token <int_val> INTNUM
+%token <intn> INTNUM
 %token <flt> FLTNUM
 %token <str_val> DIRECTIVE_NAME DIRECTIVE_VAL STRING
-%token <int_val> BYTE WORD DWORD QWORD TWORD DQWORD
-%token <int_val> DECLARE_DATA
-%token <int_val> RESERVE_SPACE
+%token <int_info> BYTE WORD DWORD QWORD TWORD DQWORD
+%token <int_info> DECLARE_DATA
+%token <int_info> RESERVE_SPACE
 %token INCBIN EQU TIMES
 %token SEG WRT NEAR SHORT FAR NOSPLIT ORG
 %token TO
 %token O16 O32 A16 A32 LOCK REPNZ REP REPZ
-%token <int_val> OPERSIZE ADDRSIZE
-%token <int_val> CR4 CRREG_NOTCR4 DRREG TRREG ST0 FPUREG_NOTST0 MMXREG XMMREG
-%token <int_val> REG_EAX REG_ECX REG_EDX REG_EBX REG_ESP REG_EBP REG_ESI REG_EDI
-%token <int_val> REG_AX REG_CX REG_DX REG_BX REG_SP REG_BP REG_SI REG_DI
-%token <int_val> REG_AL REG_CL REG_DL REG_BL REG_AH REG_CH REG_DH REG_BH
-%token <int_val> REG_ES REG_CS REG_SS REG_DS REG_FS REG_GS
-%token LEFT_OP RIGHT_OP SIGNDIV SIGNMOD
+%token <int_info> OPERSIZE ADDRSIZE
+%token <int_info> CR4 CRREG_NOTCR4 DRREG TRREG ST0 FPUREG_NOTST0 MMXREG XMMREG
+%token <int_info> REG_EAX REG_ECX REG_EDX REG_EBX
+%token <int_info> REG_ESP REG_EBP REG_ESI REG_EDI
+%token <int_info> REG_AX REG_CX REG_DX REG_BX REG_SP REG_BP REG_SI REG_DI
+%token <int_info> REG_AL REG_CL REG_DL REG_BL REG_AH REG_CH REG_DH REG_BH
+%token <int_info> REG_ES REG_CS REG_SS REG_DS REG_FS REG_GS
+%token LEFT_OP RIGHT_OP SIGNDIV SIGNMOD START_SECTION_ID
 %token <str_val> ID LOCAL_ID SPECIAL_ID
 
 /* instruction tokens (dynamically generated) */
@@ -102,9 +107,9 @@ static bytecode *nasm_parser_temp_bc;
 
 /* @TYPES@ */
 
-%type <bc> line exp instr instrbase label
+%type <bc> line exp instr instrbase
 
-%type <int_val> fpureg reg32 reg16 reg8 segreg
+%type <int_info> fpureg reg32 reg16 reg8 segreg
 %type <ea> mem memaddr memexp memfar
 %type <ea> mem8x mem16x mem32x mem64x mem80x mem128x
 %type <ea> mem8 mem16 mem32 mem64 mem80 mem128 mem1632
@@ -112,7 +117,8 @@ static bytecode *nasm_parser_temp_bc;
 %type <ea> rm8 rm16 rm32 rm64 rm128
 %type <im_val> imm imm8x imm16x imm32x imm8 imm16 imm32
 %type <exp> expr expr_no_string
-%type <str_val> explabel label_id
+%type <sym> explabel
+%type <str_val> label_id
 %type <tgt_val> target
 %type <data> dataval
 %type <datahead> datavals
@@ -164,7 +170,6 @@ datavals: dataval       {
 ;
 
 dataval: expr_no_string        { $$ = dataval_new_expr($1); }
-    | FLTNUM           { $$ = dataval_new_float($1); }
     | STRING           { $$ = dataval_new_string($1); }
     | error            {
        Error(_("expression syntax error"));
@@ -173,10 +178,12 @@ dataval: expr_no_string   { $$ = dataval_new_expr($1); }
 ;
 
 label: label_id            {
-       symrec_define_label($1, nasm_parser_cur_section, nasm_parser_prev_bc);
+       symrec_define_label($1, nasm_parser_cur_section, nasm_parser_prev_bc,
+                           1);
     }
     | label_id ':'  {
-       symrec_define_label($1, nasm_parser_cur_section, nasm_parser_prev_bc);
+       symrec_define_label($1, nasm_parser_cur_section, nasm_parser_prev_bc,
+                           1);
     }
 ;
 
@@ -194,6 +201,8 @@ directive: '[' DIRECTIVE_NAME DIRECTIVE_VAL ']'     {
            nasm_parser_cur_section = sections_switch(&nasm_parser_sections,
                                                      nasm_parser_objfmt, $3);
            nasm_parser_prev_bc = (bytecode *)NULL;
+           symrec_define_label($3, nasm_parser_cur_section, (bytecode *)NULL,
+                               1);
        } else {
            printf("Directive: Name='%s' Value='%s'\n", $2, $3);
        }
@@ -254,7 +263,7 @@ segreg:  REG_ES
 ;
 
 /* memory addresses */
-memexp: expr   { expr_simplify ($1); $$ = effaddr_new_expr($1); }
+memexp: expr   { $$ = effaddr_new_expr($1); }
 ;
 
 memaddr: memexp                    { $$ = $1; SetEASegment($$, 0); }
@@ -353,7 +362,7 @@ rm128: XMMREG       { $$ = effaddr_new_reg($1); }
 ;
 
 /* immediate values */
-imm: expr   { expr_simplify($1); $$ = immval_new_expr($1); }
+imm: expr   { $$ = immval_new_expr($1); }
 ;
 
 /* explicit immediates */
@@ -383,7 +392,8 @@ target: expr            { $$.val = $1; SetOpcodeSel(&$$.op_sel, JR_NONE); }
 
 /* expression trees */
 expr_no_string: INTNUM         { $$ = expr_new_ident(ExprInt($1)); }
-    | explabel                 { $$ = expr_new_ident(ExprSym(symrec_use($1))); }
+    | FLTNUM                   { $$ = expr_new_ident(ExprFloat($1)); }
+    | explabel                 { $$ = expr_new_ident(ExprSym($1)); }
     /*| expr '||' expr         { $$ = expr_new_tree($1, EXPR_LOR, $3); }*/
     | expr '|' expr            { $$ = expr_new_tree($1, EXPR_OR, $3); }
     | expr '^' expr            { $$ = expr_new_tree($1, EXPR_XOR, $3); }
@@ -401,7 +411,9 @@ expr_no_string: INTNUM              { $$ = expr_new_ident(ExprInt($1)); }
     | expr '-' expr            { $$ = expr_new_tree($1, EXPR_SUB, $3); }
     | expr '*' expr            { $$ = expr_new_tree($1, EXPR_MUL, $3); }
     | expr '/' expr            { $$ = expr_new_tree($1, EXPR_DIV, $3); }
+    | expr SIGNDIV expr                { $$ = expr_new_tree($1, EXPR_SIGNDIV, $3); }
     | expr '%' expr            { $$ = expr_new_tree($1, EXPR_MOD, $3); }
+    | expr SIGNMOD expr                { $$ = expr_new_tree($1, EXPR_SIGNMOD, $3); }
     | '+' expr %prec UNARYOP   { $$ = $2; }
     | '-' expr %prec UNARYOP   { $$ = expr_new_branch(EXPR_NEG, $2); }
     /*| '!' expr               { $$ = expr_new_branch(EXPR_LNOT, $2); }*/
@@ -411,13 +423,20 @@ expr_no_string: INTNUM            { $$ = expr_new_ident(ExprInt($1)); }
 
 expr: expr_no_string
     | STRING           {
-       $$ = expr_new_ident(ExprInt(ConvertCharConstToInt($1)));
+       $$ = expr_new_ident(ExprInt(intnum_new_charconst_nasm($1)));
     }
 ;
 
-explabel: ID
-    | SPECIAL_ID
-    | LOCAL_ID
+explabel: ID           { $$ = symrec_use($1); }
+    | SPECIAL_ID       { $$ = symrec_use($1); }
+    | LOCAL_ID         { $$ = symrec_use($1); }
+    | '$'              {
+       $$ = symrec_define_label("$", nasm_parser_cur_section,
+                                nasm_parser_prev_bc, 0);
+    }
+    | START_SECTION_ID {
+       $$ = symrec_use(section_get_name(nasm_parser_cur_section));
+    }
 ;
 
 instr: instrbase
@@ -440,32 +459,6 @@ instr: instrbase
 
 %%
 
-static unsigned long
-ConvertCharConstToInt(char *cc)
-{
-    unsigned long retval = 0;
-    size_t len = strlen(cc);
-
-    if (len > 4)
-       Warning(_("character constant too large, ignoring trailing characters"));
-
-    switch (len) {
-       case 4:
-           retval |= (unsigned long)cc[3];
-           retval <<= 8;
-       case 3:
-           retval |= (unsigned long)cc[2];
-           retval <<= 8;
-       case 2:
-           retval |= (unsigned long)cc[1];
-           retval <<= 8;
-       case 1:
-           retval |= (unsigned long)cc[0];
-    }
-
-    return retval;
-}
-
 void
 nasm_parser_error(const char *s)
 {
index c69c2e66ed7f236fe23eab7bfbc3062f0fbf8529..e44fcf456b57adf1390ff2a82ce62df8ff12afb9 100644 (file)
 #include <libintl.h>
 #define _(String)      gettext(String)
 
+#include "bitvect.h"
+
 #include "globals.h"
 #include "errwarn.h"
+#include "intnum.h"
 #include "floatnum.h"
 #include "expr.h"
 #include "symrec.h"
@@ -51,7 +54,6 @@ RCSID("$IdPath$");
 
 void init_table(void);
 extern int nasm_parser_lex(void);
-static unsigned long ConvertCharConstToInt(char *);
 void nasm_parser_error(const char *);
 
 extern objfmt *nasm_parser_objfmt;
@@ -65,9 +67,11 @@ static bytecode *nasm_parser_temp_bc;
 %}
 
 %union {
-    unsigned long int_val;
+    unsigned int int_info;
     char *str_val;
+    intnum *intn;
     floatnum *flt;
+    symrec *sym;
     unsigned char groupdata[4];
     effaddr *ea;
     expr *exp;
@@ -78,23 +82,24 @@ static bytecode *nasm_parser_temp_bc;
     bytecode *bc;
 }
 
-%token <int_val> INTNUM
+%token <intn> INTNUM
 %token <flt> FLTNUM
 %token <str_val> DIRECTIVE_NAME DIRECTIVE_VAL STRING
-%token <int_val> BYTE WORD DWORD QWORD TWORD DQWORD
-%token <int_val> DECLARE_DATA
-%token <int_val> RESERVE_SPACE
+%token <int_info> BYTE WORD DWORD QWORD TWORD DQWORD
+%token <int_info> DECLARE_DATA
+%token <int_info> RESERVE_SPACE
 %token INCBIN EQU TIMES
 %token SEG WRT NEAR SHORT FAR NOSPLIT ORG
 %token TO
 %token O16 O32 A16 A32 LOCK REPNZ REP REPZ
-%token <int_val> OPERSIZE ADDRSIZE
-%token <int_val> CR4 CRREG_NOTCR4 DRREG TRREG ST0 FPUREG_NOTST0 MMXREG XMMREG
-%token <int_val> REG_EAX REG_ECX REG_EDX REG_EBX REG_ESP REG_EBP REG_ESI REG_EDI
-%token <int_val> REG_AX REG_CX REG_DX REG_BX REG_SP REG_BP REG_SI REG_DI
-%token <int_val> REG_AL REG_CL REG_DL REG_BL REG_AH REG_CH REG_DH REG_BH
-%token <int_val> REG_ES REG_CS REG_SS REG_DS REG_FS REG_GS
-%token LEFT_OP RIGHT_OP SIGNDIV SIGNMOD
+%token <int_info> OPERSIZE ADDRSIZE
+%token <int_info> CR4 CRREG_NOTCR4 DRREG TRREG ST0 FPUREG_NOTST0 MMXREG XMMREG
+%token <int_info> REG_EAX REG_ECX REG_EDX REG_EBX
+%token <int_info> REG_ESP REG_EBP REG_ESI REG_EDI
+%token <int_info> REG_AX REG_CX REG_DX REG_BX REG_SP REG_BP REG_SI REG_DI
+%token <int_info> REG_AL REG_CL REG_DL REG_BL REG_AH REG_CH REG_DH REG_BH
+%token <int_info> REG_ES REG_CS REG_SS REG_DS REG_FS REG_GS
+%token LEFT_OP RIGHT_OP SIGNDIV SIGNMOD START_SECTION_ID
 %token <str_val> ID LOCAL_ID SPECIAL_ID
 
 /* instruction tokens (dynamically generated) */
@@ -102,9 +107,9 @@ static bytecode *nasm_parser_temp_bc;
 
 /* @TYPES@ */
 
-%type <bc> line exp instr instrbase label
+%type <bc> line exp instr instrbase
 
-%type <int_val> fpureg reg32 reg16 reg8 segreg
+%type <int_info> fpureg reg32 reg16 reg8 segreg
 %type <ea> mem memaddr memexp memfar
 %type <ea> mem8x mem16x mem32x mem64x mem80x mem128x
 %type <ea> mem8 mem16 mem32 mem64 mem80 mem128 mem1632
@@ -112,7 +117,8 @@ static bytecode *nasm_parser_temp_bc;
 %type <ea> rm8 rm16 rm32 rm64 rm128
 %type <im_val> imm imm8x imm16x imm32x imm8 imm16 imm32
 %type <exp> expr expr_no_string
-%type <str_val> explabel label_id
+%type <sym> explabel
+%type <str_val> label_id
 %type <tgt_val> target
 %type <data> dataval
 %type <datahead> datavals
@@ -164,7 +170,6 @@ datavals: dataval       {
 ;
 
 dataval: expr_no_string        { $$ = dataval_new_expr($1); }
-    | FLTNUM           { $$ = dataval_new_float($1); }
     | STRING           { $$ = dataval_new_string($1); }
     | error            {
        Error(_("expression syntax error"));
@@ -173,10 +178,12 @@ dataval: expr_no_string   { $$ = dataval_new_expr($1); }
 ;
 
 label: label_id            {
-       symrec_define_label($1, nasm_parser_cur_section, nasm_parser_prev_bc);
+       symrec_define_label($1, nasm_parser_cur_section, nasm_parser_prev_bc,
+                           1);
     }
     | label_id ':'  {
-       symrec_define_label($1, nasm_parser_cur_section, nasm_parser_prev_bc);
+       symrec_define_label($1, nasm_parser_cur_section, nasm_parser_prev_bc,
+                           1);
     }
 ;
 
@@ -194,6 +201,8 @@ directive: '[' DIRECTIVE_NAME DIRECTIVE_VAL ']'     {
            nasm_parser_cur_section = sections_switch(&nasm_parser_sections,
                                                      nasm_parser_objfmt, $3);
            nasm_parser_prev_bc = (bytecode *)NULL;
+           symrec_define_label($3, nasm_parser_cur_section, (bytecode *)NULL,
+                               1);
        } else {
            printf("Directive: Name='%s' Value='%s'\n", $2, $3);
        }
@@ -254,7 +263,7 @@ segreg:  REG_ES
 ;
 
 /* memory addresses */
-memexp: expr   { expr_simplify ($1); $$ = effaddr_new_expr($1); }
+memexp: expr   { $$ = effaddr_new_expr($1); }
 ;
 
 memaddr: memexp                    { $$ = $1; SetEASegment($$, 0); }
@@ -353,7 +362,7 @@ rm128: XMMREG       { $$ = effaddr_new_reg($1); }
 ;
 
 /* immediate values */
-imm: expr   { expr_simplify($1); $$ = immval_new_expr($1); }
+imm: expr   { $$ = immval_new_expr($1); }
 ;
 
 /* explicit immediates */
@@ -383,7 +392,8 @@ target: expr            { $$.val = $1; SetOpcodeSel(&$$.op_sel, JR_NONE); }
 
 /* expression trees */
 expr_no_string: INTNUM         { $$ = expr_new_ident(ExprInt($1)); }
-    | explabel                 { $$ = expr_new_ident(ExprSym(symrec_use($1))); }
+    | FLTNUM                   { $$ = expr_new_ident(ExprFloat($1)); }
+    | explabel                 { $$ = expr_new_ident(ExprSym($1)); }
     /*| expr '||' expr         { $$ = expr_new_tree($1, EXPR_LOR, $3); }*/
     | expr '|' expr            { $$ = expr_new_tree($1, EXPR_OR, $3); }
     | expr '^' expr            { $$ = expr_new_tree($1, EXPR_XOR, $3); }
@@ -401,7 +411,9 @@ expr_no_string: INTNUM              { $$ = expr_new_ident(ExprInt($1)); }
     | expr '-' expr            { $$ = expr_new_tree($1, EXPR_SUB, $3); }
     | expr '*' expr            { $$ = expr_new_tree($1, EXPR_MUL, $3); }
     | expr '/' expr            { $$ = expr_new_tree($1, EXPR_DIV, $3); }
+    | expr SIGNDIV expr                { $$ = expr_new_tree($1, EXPR_SIGNDIV, $3); }
     | expr '%' expr            { $$ = expr_new_tree($1, EXPR_MOD, $3); }
+    | expr SIGNMOD expr                { $$ = expr_new_tree($1, EXPR_SIGNMOD, $3); }
     | '+' expr %prec UNARYOP   { $$ = $2; }
     | '-' expr %prec UNARYOP   { $$ = expr_new_branch(EXPR_NEG, $2); }
     /*| '!' expr               { $$ = expr_new_branch(EXPR_LNOT, $2); }*/
@@ -411,13 +423,20 @@ expr_no_string: INTNUM            { $$ = expr_new_ident(ExprInt($1)); }
 
 expr: expr_no_string
     | STRING           {
-       $$ = expr_new_ident(ExprInt(ConvertCharConstToInt($1)));
+       $$ = expr_new_ident(ExprInt(intnum_new_charconst_nasm($1)));
     }
 ;
 
-explabel: ID
-    | SPECIAL_ID
-    | LOCAL_ID
+explabel: ID           { $$ = symrec_use($1); }
+    | SPECIAL_ID       { $$ = symrec_use($1); }
+    | LOCAL_ID         { $$ = symrec_use($1); }
+    | '$'              {
+       $$ = symrec_define_label("$", nasm_parser_cur_section,
+                                nasm_parser_prev_bc, 0);
+    }
+    | START_SECTION_ID {
+       $$ = symrec_use(section_get_name(nasm_parser_cur_section));
+    }
 ;
 
 instr: instrbase
@@ -440,32 +459,6 @@ instr: instrbase
 
 %%
 
-static unsigned long
-ConvertCharConstToInt(char *cc)
-{
-    unsigned long retval = 0;
-    size_t len = strlen(cc);
-
-    if (len > 4)
-       Warning(_("character constant too large, ignoring trailing characters"));
-
-    switch (len) {
-       case 4:
-           retval |= (unsigned long)cc[3];
-           retval <<= 8;
-       case 3:
-           retval |= (unsigned long)cc[2];
-           retval <<= 8;
-       case 2:
-           retval |= (unsigned long)cc[1];
-           retval <<= 8;
-       case 1:
-           retval |= (unsigned long)cc[0];
-    }
-
-    return retval;
-}
-
 void
 nasm_parser_error(const char *s)
 {
index 5329e1b4890575b1fb3bb1bb0254dee29c97d672..17c4a99681afa3819d30b6f8c5a206a73ce8ea4b 100644 (file)
 #include <libintl.h>
 #define _(String)      gettext(String)
 
+#include "bitvect.h"
+
 #include "errwarn.h"
+#include "intnum.h"
 #include "floatnum.h"
 #include "expr.h"
 #include "symrec.h"
@@ -87,31 +90,37 @@ WS       [ \t\r]
 
     /* standard decimal integer */
 {DIGIT}+ {
-    yylval.int_val = strtoul(yytext, (char **)NULL, 10);
+    yylval.intn = intnum_new_dec(yytext);
     return INTNUM;
 }
 
     /* 10010011b - binary number */
 {BINDIGIT}+b {
-    yylval.int_val = strtoul(yytext, (char **)NULL, 2);
+    yytext[strlen(yytext)] = '\0';  /* strip off 'b' */
+    yylval.intn = intnum_new_bin(yytext);
     return INTNUM;
 }
 
     /* 777q - octal number */
 {OCTDIGIT}+q {
-    yylval.int_val = strtoul(yytext, (char **)NULL, 8);
+    yytext[strlen(yytext)] = '\0';  /* strip off 'q' */
+    yylval.intn = intnum_new_oct(yytext);
     return INTNUM;
 }
 
     /* 0AAh form of hexidecimal number */
 0{HEXDIGIT}+h {
-    yylval.int_val = strtoul(yytext+1, (char **)NULL, 16);
+    yytext[strlen(yytext)] = '\0';  /* strip off 'h' */
+    yylval.intn = intnum_new_hex(yytext);
     return INTNUM;
 }
 
     /* $0AA and 0xAA forms of hexidecimal number */
 (\$0|0x){HEXDIGIT}+ {
-    yylval.int_val = strtoul(yytext+2, (char **)NULL, 16);
+    if (yytext[1] == 'x')
+       yylval.intn = intnum_new_hex(yytext+2); /* 0x format, skip 0 and x */
+    else
+       yylval.intn = intnum_new_hex(yytext+1); /* $0 format, don't skip 0 */
     return INTNUM;
 }
 
@@ -182,25 +191,25 @@ WS       [ \t\r]
 }
 
     /* size specifiers */
-byte   { yylval.int_val = 1; return BYTE; }
-word   { yylval.int_val = 2; return WORD; }
-dword  { yylval.int_val = 4; return DWORD; }
-qword  { yylval.int_val = 8; return QWORD; }
-tword  { yylval.int_val = 10; return TWORD; }
-dqword { yylval.int_val = 16; return DQWORD; }
+byte   { yylval.int_info = 1; return BYTE; }
+word   { yylval.int_info = 2; return WORD; }
+dword  { yylval.int_info = 4; return DWORD; }
+qword  { yylval.int_info = 8; return QWORD; }
+tword  { yylval.int_info = 10; return TWORD; }
+dqword { yylval.int_info = 16; return DQWORD; }
 
     /* pseudo-instructions */
-db     { yylval.int_val = 1; return DECLARE_DATA; }
-dw     { yylval.int_val = 2; return DECLARE_DATA; }
-dd     { yylval.int_val = 4; return DECLARE_DATA; }
-dq     { yylval.int_val = 8; return DECLARE_DATA; }
-dt     { yylval.int_val = 10; return DECLARE_DATA; }
-
-resb   { yylval.int_val = 1; return RESERVE_SPACE; }
-resw   { yylval.int_val = 2; return RESERVE_SPACE; }
-resd   { yylval.int_val = 4; return RESERVE_SPACE; }
-resq   { yylval.int_val = 8; return RESERVE_SPACE; }
-rest   { yylval.int_val = 10; return RESERVE_SPACE; }
+db     { yylval.int_info = 1; return DECLARE_DATA; }
+dw     { yylval.int_info = 2; return DECLARE_DATA; }
+dd     { yylval.int_info = 4; return DECLARE_DATA; }
+dq     { yylval.int_info = 8; return DECLARE_DATA; }
+dt     { yylval.int_info = 10; return DECLARE_DATA; }
+
+resb   { yylval.int_info = 1; return RESERVE_SPACE; }
+resw   { yylval.int_info = 2; return RESERVE_SPACE; }
+resd   { yylval.int_info = 4; return RESERVE_SPACE; }
+resq   { yylval.int_info = 8; return RESERVE_SPACE; }
+rest   { yylval.int_info = 10; return RESERVE_SPACE; }
 
 incbin { return INCBIN; }
 
@@ -221,11 +230,11 @@ org       { return ORG; }
 to     { return TO; }
 
     /* operand size overrides */
-o16    { yylval.int_val = 16; return OPERSIZE; }
-o32    { yylval.int_val = 32; return OPERSIZE; }
+o16    { yylval.int_info = 16; return OPERSIZE; }
+o32    { yylval.int_info = 32; return OPERSIZE; }
     /* address size overrides */
-a16    { yylval.int_val = 16; return ADDRSIZE; }
-a32    { yylval.int_val = 32; return ADDRSIZE; }
+a16    { yylval.int_info = 16; return ADDRSIZE; }
+a32    { yylval.int_info = 32; return ADDRSIZE; }
 
     /* instruction prefixes */
 lock   { return LOCK; }
@@ -236,62 +245,63 @@ repe      { return REPZ; }
 repz   { return REPZ; }
 
     /* control, debug, and test registers */
-cr4            { yylval.int_val = 4; return CR4; }
-cr[023]                { yylval.int_val = yytext[2]-'0'; return CRREG_NOTCR4; }
-dr[0-367]      { yylval.int_val = yytext[2]-'0'; return DRREG; }
-tr[3-7]                { yylval.int_val = yytext[2]-'0'; return TRREG; }
+cr4            { yylval.int_info = 4; return CR4; }
+cr[023]                { yylval.int_info = yytext[2]-'0'; return CRREG_NOTCR4; }
+dr[0-367]      { yylval.int_info = yytext[2]-'0'; return DRREG; }
+tr[3-7]                { yylval.int_info = yytext[2]-'0'; return TRREG; }
 
     /* floating point, MMX, and SSE registers */
-st0        { yylval.int_val = 0; return ST0; }
-st[1-7]            { yylval.int_val = yytext[2]-'0'; return FPUREG_NOTST0; }
-mm[0-7]            { yylval.int_val = yytext[2]-'0'; return MMXREG; }
-xmm[0-7]    { yylval.int_val = yytext[3]-'0'; return XMMREG; }
+st0        { yylval.int_info = 0; return ST0; }
+st[1-7]            { yylval.int_info = yytext[2]-'0'; return FPUREG_NOTST0; }
+mm[0-7]            { yylval.int_info = yytext[2]-'0'; return MMXREG; }
+xmm[0-7]    { yylval.int_info = yytext[3]-'0'; return XMMREG; }
 
     /* integer registers */
-eax    { yylval.int_val = 0; return REG_EAX; }
-ecx    { yylval.int_val = 1; return REG_ECX; }
-edx    { yylval.int_val = 2; return REG_EDX; }
-ebx    { yylval.int_val = 3; return REG_EBX; }
-esp    { yylval.int_val = 4; return REG_ESP; }
-ebp    { yylval.int_val = 5; return REG_EBP; }
-esi    { yylval.int_val = 6; return REG_ESI; }
-edi    { yylval.int_val = 7; return REG_EDI; }
-
-ax     { yylval.int_val = 0; return REG_AX; }
-cx     { yylval.int_val = 1; return REG_CX; }
-dx     { yylval.int_val = 2; return REG_DX; }
-bx     { yylval.int_val = 3; return REG_BX; }
-sp     { yylval.int_val = 4; return REG_SP; }
-bp     { yylval.int_val = 5; return REG_BP; }
-si     { yylval.int_val = 6; return REG_SI; }
-di     { yylval.int_val = 7; return REG_DI; }
-
-al     { yylval.int_val = 0; return REG_AL; }
-cl     { yylval.int_val = 1; return REG_CL; }
-dl     { yylval.int_val = 2; return REG_DL; }
-bl     { yylval.int_val = 3; return REG_BL; }
-ah     { yylval.int_val = 4; return REG_AH; }
-ch     { yylval.int_val = 5; return REG_CH; }
-dh     { yylval.int_val = 6; return REG_DH; }
-bh     { yylval.int_val = 7; return REG_BH; }
+eax    { yylval.int_info = 0; return REG_EAX; }
+ecx    { yylval.int_info = 1; return REG_ECX; }
+edx    { yylval.int_info = 2; return REG_EDX; }
+ebx    { yylval.int_info = 3; return REG_EBX; }
+esp    { yylval.int_info = 4; return REG_ESP; }
+ebp    { yylval.int_info = 5; return REG_EBP; }
+esi    { yylval.int_info = 6; return REG_ESI; }
+edi    { yylval.int_info = 7; return REG_EDI; }
+
+ax     { yylval.int_info = 0; return REG_AX; }
+cx     { yylval.int_info = 1; return REG_CX; }
+dx     { yylval.int_info = 2; return REG_DX; }
+bx     { yylval.int_info = 3; return REG_BX; }
+sp     { yylval.int_info = 4; return REG_SP; }
+bp     { yylval.int_info = 5; return REG_BP; }
+si     { yylval.int_info = 6; return REG_SI; }
+di     { yylval.int_info = 7; return REG_DI; }
+
+al     { yylval.int_info = 0; return REG_AL; }
+cl     { yylval.int_info = 1; return REG_CL; }
+dl     { yylval.int_info = 2; return REG_DL; }
+bl     { yylval.int_info = 3; return REG_BL; }
+ah     { yylval.int_info = 4; return REG_AH; }
+ch     { yylval.int_info = 5; return REG_CH; }
+dh     { yylval.int_info = 6; return REG_DH; }
+bh     { yylval.int_info = 7; return REG_BH; }
 
     /* segment registers */
-es     { yylval.int_val = 0; return REG_ES; }
-cs     { yylval.int_val = 1; return REG_CS; }
-ss     { yylval.int_val = 2; return REG_SS; }
-ds     { yylval.int_val = 3; return REG_DS; }
-fs     { yylval.int_val = 4; return REG_FS; }
-gs     { yylval.int_val = 5; return REG_GS; }
+es     { yylval.int_info = 0; return REG_ES; }
+cs     { yylval.int_info = 1; return REG_CS; }
+ss     { yylval.int_info = 2; return REG_SS; }
+ds     { yylval.int_info = 3; return REG_DS; }
+fs     { yylval.int_info = 4; return REG_FS; }
+gs     { yylval.int_info = 5; return REG_GS; }
 
     /* operators */
 "<<"                   { return LEFT_OP; }
 ">>"                   { return RIGHT_OP; }
 "//"                   { return SIGNDIV; }
 "%%"                   { return SIGNMOD; }
-[-+|^&*/%~():[\],]     { return yytext[0]; }
+"$$"                   { return START_SECTION_ID; }
+[-+|^&*/%~$():[\],]    { return yytext[0]; }
 
     /* special non-local ..@label and labels like ..start */
-$$|$|\.\.[a-z0-9_$#@~.?]+ {
+\.\.[a-z0-9_$#@~.?]+ {
     yylval.str_val = xstrdup(yytext);
     return SPECIAL_ID;
 }
index e655a5c2ec518ccdf2fda24f27ddc07f11313468..d9db4be3f6c13c04614840a2728e704a06964f9f 100644 (file)
@@ -124,8 +124,42 @@ sections_switch(sectionhead *headp, objfmt *of, const char *name)
     return s;
 }
 
+void
+sections_print(sectionhead *headp)
+{
+    section *cur;
+    
+    STAILQ_FOREACH(cur, headp, link)
+       section_print(cur);
+}
+
 bytecodehead *
 section_get_bytecodes(section *sect)
 {
     return &sect->bc;
 }
+
+const char *
+section_get_name(const section *sect)
+{
+    return sect->name;
+}
+
+void
+section_print(const section *sect)
+{
+    printf("***SECTION %s***\n", sect->name);
+    printf(" type=");
+    switch (sect->type) {
+       case SECTION_GENERAL:
+           printf("general\n");
+           break;
+       case SECTION_ABSOLUTE:
+           printf("absolute\n");
+           printf("start=%lu\n", sect->data.start);
+           break;
+    }
+
+    printf(" Bytecodes:\n");
+    bytecodes_print(&sect->bc);
+}
index ff881721cacf0b115cc488415ea0658672bccecf..93aa3de4bf5e8824fe4bbdc355d4a124ee90eda8 100644 (file)
@@ -36,5 +36,11 @@ section *sections_initialize(sectionhead *headp, struct objfmt_s *of);
 section *sections_switch(sectionhead *headp, struct objfmt_s *of,
                         const char *name);
 
+void sections_print(sectionhead *headp);
+
 bytecodehead *section_get_bytecodes(section *sect);
+
+const char *section_get_name(const section *sect);
+
+void section_print(const section *sect);
 #endif
diff --git a/src/strtoul.c b/src/strtoul.c
deleted file mode 100644 (file)
index 9eedc36..0000000
+++ /dev/null
@@ -1,119 +0,0 @@
-/* $IdPath$
- * strtoul() implementation for systems that don't have it.
- *
- * Copyright (c) 1990, 1993
- *     The Regents of the University of California.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the University nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)strtoul.c  8.1 (Berkeley) 6/4/93";
-#endif /* LIBC_SCCS and not lint */
-
-#ifdef HAVE_CONFIG_H
-# include "config.h"
-#endif
-
-#include "util.h"
-
-#ifdef HAVE_LIMITS_H
-# include <limits.h>
-#endif
-#include <ctype.h>
-#include <errno.h>
-
-#ifdef STDC_HEADERS
-# include <stdlib.h>
-#endif
-
-RCSID("$IdPath$");
-
-/*
- * Convert a string to an unsigned long integer.
- *
- * Ignores `locale' stuff.  Assumes that the upper and lower case
- * alphabets and digits are each contiguous.
- */
-unsigned long
-strtoul(const char *nptr,
-       char **endptr,
-       int base)
-{
-       const char *s = nptr;
-       unsigned long acc;
-       unsigned char c;
-       unsigned long cutoff;
-       int neg = 0, any, cutlim;
-
-       /*
-        * See strtol for comments as to the logic used.
-        */
-       do {
-               c = *s++;
-       } while (isspace(c));
-       if (c == '-') {
-               neg = 1;
-               c = *s++;
-       } else if (c == '+')
-               c = *s++;
-       if ((base == 0 || base == 16) &&
-           c == '0' && (*s == 'x' || *s == 'X')) {
-               c = s[1];
-               s += 2;
-               base = 16;
-       }
-       if (base == 0)
-               base = c == '0' ? 8 : 10;
-       cutoff = (unsigned long)ULONG_MAX / (unsigned long)base;
-       cutlim = (unsigned long)ULONG_MAX % (unsigned long)base;
-       for (acc = 0, any = 0;; c = *s++) {
-               if (!isascii(c))
-                       break;
-               if (isdigit(c))
-                       c -= '0';
-               else if (isalpha(c))
-                       c -= isupper(c) ? 'A' - 10 : 'a' - 10;
-               else
-                       break;
-               if (c >= base)
-                       break;
-               if (any < 0 || acc > cutoff || (acc == cutoff && c > cutlim))
-                       any = -1;
-               else {
-                       any = 1;
-                       acc *= base;
-                       acc += c;
-               }
-       }
-       if (any < 0) {
-               acc = ULONG_MAX;
-               errno = ERANGE;
-       } else if (neg)
-               acc = -acc;
-       if (endptr != 0)
-               *endptr = (char *)(any ? s - 1 : nptr);
-       return (acc);
-}
index 639d37e2c21aa4c17ad2b05b77888d176f7d51aa..d18f352e93eb2c6cdd3ba3c46abee3b15c04c551 100644 (file)
@@ -25,6 +25,8 @@
 
 #include "util.h"
 
+#include <stdio.h>
+
 #ifdef STDC_HEADERS
 # include <stdlib.h>
 # include <string.h>
@@ -36,6 +38,7 @@
 #include "globals.h"
 #include "errwarn.h"
 #include "floatnum.h"
+#include "expr.h"
 #include "symrec.h"
 
 #include "bytecode.h"
@@ -48,13 +51,13 @@ typedef enum {
     SYM_NOSTATUS = 0,
     SYM_USED = 1 << 0,         /* for using variables before definition */
     SYM_DEFINED = 1 << 1,      /* once it's been defined in the file */
-    SYM_VALUED = 1 << 2                /* once its value has been determined */
+    SYM_VALUED = 1 << 2,       /* once its value has been determined */
+    SYM_NOTINTABLE = 1 << 3    /* if it's not in sym_table (ex. '$') */
 } SymStatus;
 
 typedef enum {
     SYM_UNKNOWN,               /* for unknown type (COMMON/EXTERN) */
-    SYM_CONSTANT_INT,          /* for EQU defined symbols (integers) */
-    SYM_CONSTANT_FLOAT,                /*  (floating point) */
+    SYM_EQU,                   /* for EQU defined symbols (expressions) */
     SYM_LABEL                  /* for labels */
 } SymType;
 
@@ -66,8 +69,7 @@ struct symrec {
     char *filename;            /* file and line */
     unsigned long line;                /*  symbol was first declared or used on */
     union {
-       unsigned long int_val;  /* integer constant */
-       floatnum *flt;          /* floating point constant */
+       expr *expn;             /* equ value */
        struct label_s {        /* bytecode immediately preceding a label */
            section *sect;
            bytecode *bc;
@@ -76,56 +78,60 @@ struct symrec {
 };
 
 /* private functions */
-static symrec *symrec_get_or_new(const char *);
-static symrec *symrec_define(const char *, SymType type);
+static symrec *symrec_get_or_new(const char *name, int in_table);
+static symrec *symrec_define(const char *name, SymType type, int in_table);
 
 /* The symbol table: a ternary tree. */
 static ternary_tree sym_table = (ternary_tree)NULL;
 
 /* create a new symrec */
 static symrec *
-symrec_get_or_new(const char *name)
+symrec_get_or_new(const char *name, int in_table)
 {
     symrec *rec, *rec2;
 
     rec = xmalloc(sizeof(symrec));
-    rec2 = ternary_insert(&sym_table, name, rec, 0);
+    if (in_table) {
+       rec2 = ternary_insert(&sym_table, name, rec, 0);
 
-    if (rec2 != rec) {
-       free(rec);
-       return rec2;
-    }
+       if (rec2 != rec) {
+           free(rec);
+           return rec2;
+       }
+       rec->status = SYM_NOSTATUS;
+    } else
+       rec->status = SYM_NOTINTABLE;
 
     rec->name = xstrdup(name);
     rec->type = SYM_UNKNOWN;
     rec->filename = xstrdup(in_filename);
     rec->line = line_number;
-    rec->status = SYM_NOSTATUS;
     rec->visibility = SYM_LOCAL;
 
     return rec;
 }
 
-/* call a function with each symrec.  stop early if 0 returned */
-void
-symrec_foreach(int (*func) (const char *name, symrec *rec))
+/* Call a function with each symrec.  Stops early if 0 returned by func.
+   Returns 0 if stopped early. */
+int
+symrec_foreach(int (*func) (symrec *sym))
 {
-    /* TODO */
+    return ternary_traverse(sym_table, (int (*) (void *))func);
 }
 
 symrec *
 symrec_use(const char *name)
 {
-    symrec *rec = symrec_get_or_new(name);
+    symrec *rec = symrec_get_or_new(name, 1);
 
     rec->status |= SYM_USED;
     return rec;
 }
 
 static symrec *
-symrec_define(const char *name, SymType type)
+symrec_define(const char *name, SymType type, int in_table)
 {
-    symrec *rec = symrec_get_or_new(name);
+    symrec *rec = symrec_get_or_new(name, in_table);
 
     /* Has it been defined before (either by DEFINED or COMMON/EXTERN)? */
     if (rec->status & SYM_DEFINED) {
@@ -140,27 +146,19 @@ symrec_define(const char *name, SymType type)
 }
 
 symrec *
-symrec_define_constant_int(const char *name, unsigned long int_val)
+symrec_define_equ(const char *name, expr *e)
 {
-    symrec *rec = symrec_define(name, SYM_CONSTANT_INT);
-    rec->value.int_val = int_val;
+    symrec *rec = symrec_define(name, SYM_EQU, 1);
+    rec->value.expn = e;
     rec->status |= SYM_VALUED;
     return rec;
 }
 
 symrec *
-symrec_define_constant_float(const char *name, floatnum *flt)
+symrec_define_label(const char *name, section *sect, bytecode *precbc,
+                   int in_table)
 {
-    symrec *rec = symrec_define(name, SYM_CONSTANT_FLOAT);
-    rec->value.flt = flt;
-    rec->status |= SYM_VALUED;
-    return rec;
-}
-
-symrec *
-symrec_define_label(const char *name, section *sect, bytecode *precbc)
-{
-    symrec *rec = symrec_define(name, SYM_LABEL);
+    symrec *rec = symrec_define(name, SYM_LABEL, in_table);
     rec->value.label.sect = sect;
     rec->value.label.bc = precbc;
     return rec;
@@ -169,7 +167,7 @@ symrec_define_label(const char *name, section *sect, bytecode *precbc)
 symrec *
 symrec_declare(const char *name, SymVisibility vis)
 {
-    symrec *rec = symrec_get_or_new(name);
+    symrec *rec = symrec_get_or_new(name, 1);
 
     /* Don't allow EXTERN and COMMON if symbol has already been DEFINED. */
     /* Also, EXTERN and COMMON are mutually exclusive. */
@@ -188,7 +186,7 @@ symrec_declare(const char *name, SymVisibility vis)
     }
     return rec;
 }
-
+#if 0
 int
 symrec_get_int_value(const symrec *sym, unsigned long *ret_val,
                     int resolve_label)
@@ -224,9 +222,67 @@ symrec_get_int_value(const symrec *sym, unsigned long *ret_val,
     /* We can't get the value right now. */
     return 0;
 }
-
+#endif
 const char *
 symrec_get_name(const symrec *sym)
 {
     return sym->name;
 }
+
+void
+symrec_print(const symrec *sym)
+{
+    printf("---Symbol `%s'---\n", sym->name);
+
+    switch (sym->type) {
+       case SYM_UNKNOWN:
+           printf("-Unknown (Common/Extern)-\n");
+           break;
+       case SYM_EQU:
+           printf("_EQU_\n");
+           printf("Expn=");
+           expr_print(sym->value.expn);
+           printf("\n");
+           break;
+       case SYM_LABEL:
+           printf("_Label_\n");
+           printf("Section=`%s'\n", section_get_name(sym->value.label.sect));
+           if (!sym->value.label.bc)
+               printf("[First bytecode]\n");
+           else {
+               printf("[Preceding bytecode]\n");
+               bytecode_print(sym->value.label.bc);
+           }
+           break;
+    }
+
+    printf("Status=");
+    if (sym->status == SYM_NOSTATUS)
+       printf("None\n");
+    else {
+       if (sym->status & SYM_USED)
+           printf("Used,");
+       if (sym->status & SYM_DEFINED)
+           printf("Defined,");
+       if (sym->status & SYM_VALUED)
+           printf("Valued,");
+       if (sym->status & SYM_NOTINTABLE)
+           printf("Not in Table,");
+       printf("\n");
+    }
+
+    printf("Visibility=");
+    if (sym->visibility == SYM_LOCAL)
+       printf("Local\n");
+    else {
+       if (sym->visibility & SYM_GLOBAL)
+           printf("Global,");
+       if (sym->visibility & SYM_COMMON)
+           printf("Common,");
+       if (sym->visibility & SYM_EXTERN)
+           printf("Extern,");
+       printf("\n");
+    }
+
+    printf("Filename=\"%s\" Line Number=%lu\n", sym->filename, sym->line);
+}
index 3b4cd8c3f73ba00756727a68d9d24db4f235a060..2f136021e5f7ed1aadb744b1cc3f67a71880c878 100644 (file)
@@ -22,9 +22,9 @@
 #ifndef YASM_SYMREC_H
 #define YASM_SYMREC_H
 
-#ifndef YASM_FLOATNUM
-#define YASM_FLOATNUM
-typedef struct floatnum floatnum;
+#ifndef YASM_EXPR
+#define YASM_EXPR
+typedef struct expr expr;
 #endif
 
 #ifndef YASM_SECTION
@@ -51,9 +51,10 @@ typedef struct symrec symrec;
 #endif
 
 symrec *symrec_use(const char *name);
-symrec *symrec_define_constant_int(const char *name, unsigned long int_val);
-symrec *symrec_define_constant_float(const char *name, floatnum *flt);
-symrec *symrec_define_label(const char *name, section *sect, bytecode *precbc);
+symrec *symrec_define_equ(const char *name, expr *e);
+/* in_table specifies if the label should be inserted into the symbol table. */
+symrec *symrec_define_label(const char *name, section *sect, bytecode *precbc,
+                           int in_table);
 symrec *symrec_declare(const char *name, SymVisibility vis);
 
 /* Get the numeric 32-bit value of a symbol if possible.
@@ -66,6 +67,7 @@ int symrec_get_int_value(const symrec *sym, unsigned long *ret_val,
 
 const char *symrec_get_name(const symrec *sym);
 
-void symrec_foreach(int (*func) (const char *name, symrec *rec));
+int symrec_foreach(int (*func) (symrec *sym));
 
+void symrec_print(const symrec *sym);
 #endif
index b1320d545a9a68529a3549d75dd71074a25c75fa..7b7b920f3dfb7a6432c70a36799480f7e17ecfe9 100644 (file)
@@ -3,6 +3,9 @@
 
    Contributed by Daniel Berlin (dan@cgsoftware.com)
 
+   ternary_traverse by Peter Johnson (adapted from code by Jon Bentley and
+   Robert Sedgewick).
+
    This program is free software; you can redistribute it and/or modify it
    under the terms of the GNU General Public License as published by the
    Free Software Foundation; either version 2, or (at your option) any
@@ -160,3 +163,23 @@ ternary_recursivesearch (ternary_tree p, const char *s)
       return ternary_recursivesearch (p->eqkid, ++s);
     }
 }
+
+/* Traverse over tree, calling callback function for each leaf. 
+   Stops early if func returns 0. */
+int
+ternary_traverse (ternary_tree p, int (*func) (void *d))
+{
+  if (!p)
+    return 1;
+  if (ternary_traverse (p->lokid, func) == 0)
+    return 0;
+  if (p->splitchar)
+    {
+      if (ternary_traverse (p->eqkid, func) == 0)
+       return 0;
+    }
+  else
+    if (func (p->eqkid) == 0)
+      return 0;
+  return ternary_traverse (p->hikid, func);
+}
index 8e0ff6a2c3a820aaea43b0c3206c6b3bb2e3d423..e9f78b80a4c62f736798a7f7c6dbb2b554b16ef9 100644 (file)
@@ -47,4 +47,8 @@ void ternary_cleanup (ternary_tree p);
 /* Search the ternary tree for string S, returning the data associated
    with it if found. */
 void *ternary_search (ternary_tree p, const char *s);
+
+/* Traverse over tree, calling callback function for each leaf. 
+   Stops early if func returns 0. */
+int ternary_traverse (ternary_tree p, int (*func) (void *d));
 #endif
index d768e3c7adf1a8235cf213d4cc6a03514da679a7..78ef88e8b3e86922861aa5227f1cdb42262d16e6 100644 (file)
@@ -287,7 +287,8 @@ START_TEST(test_get_single_normalized)
 
     for (i=0; i<num; i++) {
        get_common_setup(vals, i);
-       fail_unless(floatnum_get_single(outval, flt) == vals[i].ret32, ret_msg);
+       fail_unless(floatnum_get_sized(outval, flt, 4) == vals[i].ret32,
+                   ret_msg);
        fail_unless(get_common_check_result(4, outval, vals[i].result32) == 0,
                    result_msg);
     }
@@ -302,7 +303,8 @@ START_TEST(test_get_single_normalized_edgecase)
 
     for (i=0; i<num; i++) {
        get_common_setup(vals, i);
-       fail_unless(floatnum_get_single(outval, flt) == vals[i].ret32, ret_msg);
+       fail_unless(floatnum_get_sized(outval, flt, 4) == vals[i].ret32,
+                   ret_msg);
        fail_unless(get_common_check_result(4, outval, vals[i].result32) == 0,
                    result_msg);
     }
@@ -321,7 +323,8 @@ START_TEST(test_get_double_normalized)
 
     for (i=0; i<num; i++) {
        get_common_setup(vals, i);
-       fail_unless(floatnum_get_double(outval, flt) == vals[i].ret64, ret_msg);
+       fail_unless(floatnum_get_sized(outval, flt, 8) == vals[i].ret64,
+                   ret_msg);
        fail_unless(get_common_check_result(8, outval, vals[i].result64) == 0,
                    result_msg);
     }
@@ -336,7 +339,8 @@ START_TEST(test_get_double_normalized_edgecase)
 
     for (i=0; i<num; i++) {
        get_common_setup(vals, i);
-       fail_unless(floatnum_get_double(outval, flt) == vals[i].ret64, ret_msg);
+       fail_unless(floatnum_get_sized(outval, flt, 8) == vals[i].ret64,
+                   ret_msg);
        fail_unless(get_common_check_result(8, outval, vals[i].result64) == 0,
                    result_msg);
     }
@@ -355,7 +359,7 @@ START_TEST(test_get_extended_normalized)
 
     for (i=0; i<num; i++) {
        get_common_setup(vals, i);
-       fail_unless(floatnum_get_extended(outval, flt) == vals[i].ret80,
+       fail_unless(floatnum_get_sized(outval, flt, 10) == vals[i].ret80,
                    ret_msg);
        fail_unless(get_common_check_result(10, outval, vals[i].result80) == 0,
                    result_msg);
@@ -371,7 +375,7 @@ START_TEST(test_get_extended_normalized_edgecase)
 
     for (i=0; i<num; i++) {
        get_common_setup(vals, i);
-       fail_unless(floatnum_get_extended(outval, flt) == vals[i].ret80,
+       fail_unless(floatnum_get_sized(outval, flt, 10) == vals[i].ret80,
                    ret_msg);
        fail_unless(get_common_check_result(10, outval, vals[i].result80) == 0,
                    result_msg);
index 558715f9de49f7315e72a27d31d5a2eed8b2a234..670275c673b7fe924f16e7bb8c5a43987db05cf8 100644 (file)
@@ -33,10 +33,6 @@ char *xstrdup(const char *str);
 char *strsep(char **stringp, const char *delim);
 #endif
 
-#if !defined(HAVE_STRTOUL) || defined(HAVE_GNU_C_LIBRARY)
-unsigned long strtoul(const char *nptr, char **endptr, int base);
-#endif
-
 #ifndef HAVE_STRCASECMP
 # ifdef HAVE_STRICMP
 #  define strcasecmp(x, y)     stricmp(x, y)
diff --git a/util.h b/util.h
index 558715f9de49f7315e72a27d31d5a2eed8b2a234..670275c673b7fe924f16e7bb8c5a43987db05cf8 100644 (file)
--- a/util.h
+++ b/util.h
@@ -33,10 +33,6 @@ char *xstrdup(const char *str);
 char *strsep(char **stringp, const char *delim);
 #endif
 
-#if !defined(HAVE_STRTOUL) || defined(HAVE_GNU_C_LIBRARY)
-unsigned long strtoul(const char *nptr, char **endptr, int base);
-#endif
-
 #ifndef HAVE_STRCASECMP
 # ifdef HAVE_STRICMP
 #  define strcasecmp(x, y)     stricmp(x, y)