[nasm:debug-macros] data: replace data->sign with a flags field

nasm-bot for H. Peter Anvin (Intel) hpa at zytor.com
Thu Jul 9 21:00:04 PDT 2020


Commit-ID:  79fd2b96457e923c429ce91cdad87899e4b17535
Gitweb:     http://repo.or.cz/w/nasm.git?a=commitdiff;h=79fd2b96457e923c429ce91cdad87899e4b17535
Author:     H. Peter Anvin (Intel) <hpa at zytor.com>
AuthorDate: Thu, 9 Jul 2020 20:58:10 -0700
Committer:  H. Peter Anvin (Intel) <hpa at zytor.com>
CommitDate: Thu, 9 Jul 2020 20:58:10 -0700

data: replace data->sign with a flags field

Signed and unsigned are really two flags; might as well allow this
field to contain additional flags.

Signed-off-by: H. Peter Anvin (Intel) <hpa at zytor.com>


---
 asm/assemble.c  | 69 ++++++++++++++++++++++++++-------------------------------
 include/nasm.h  | 13 ++++++-----
 output/legacy.c |  4 ++--
 output/outdbg.c | 39 ++++++++++++++++++++++----------
 4 files changed, 68 insertions(+), 57 deletions(-)

diff --git a/asm/assemble.c b/asm/assemble.c
index 3d85e472..776cde03 100644
--- a/asm/assemble.c
+++ b/asm/assemble.c
@@ -301,24 +301,16 @@ static void warn_overflow_const(int64_t data, int size)
         warn_overflow(size);
 }
 
-static void warn_overflow_out(int64_t data, int size, enum out_sign sign)
+static void warn_overflow_out(int64_t data, int size, enum out_flags flags)
 {
     bool err;
 
-    switch (sign) {
-    case OUT_WRAP:
-        err = overflow_general(data, size);
-        break;
-    case OUT_SIGNED:
+    if (flags & OUT_SIGNED)
         err = overflow_signed(data, size);
-        break;
-    case OUT_UNSIGNED:
+    else if (flags & OUT_UNSIGNED)
         err = overflow_unsigned(data, size);
-        break;
-    default:
-        panic();
-        break;
-    }
+    else
+        err = overflow_general(data, size);
 
     if (err)
         warn_overflow(size);
@@ -393,11 +385,14 @@ static void out(struct out_data *data)
         nasm_assert(data->size <= 8);
         asize = data->size;
         amax = ofmt->maxbits >> 3; /* Maximum address size in bytes */
-        if ((ofmt->flags & OFMT_KEEP_ADDR) == 0 && data->tsegment == fixseg &&
+        if (!(ofmt->flags & OFMT_KEEP_ADDR) &&
+            data->tsegment == fixseg &&
             data->twrt == NO_SEG) {
-            if (asize >= (size_t)(data->bits >> 3))
-                data->sign = OUT_WRAP; /* Support address space wrapping for low-bit modes */
-            warn_overflow_out(addrval, asize, data->sign);
+            if (asize >= (size_t)(data->bits >> 3)) {
+                 /* Support address space wrapping for low-bit modes */
+                data->flags &= ~OUT_SIGNMASK;
+            }
+            warn_overflow_out(addrval, asize, data->flags);
             xdata.q = cpu_to_le64(addrval);
             data->data = xdata.b;
             data->type = OUT_RAWDATA;
@@ -428,7 +423,7 @@ static void out(struct out_data *data)
         dfmt->linenum(lnfname, lineno, data->segment);
 
     if (asize > amax) {
-        if (data->type == OUT_RELADDR || data->sign == OUT_SIGNED) {
+        if (data->type == OUT_RELADDR || (data->flags & OUT_SIGNED)) {
             nasm_nonfatal("%u-bit signed relocation unsupported by output format %s",
                           (unsigned int)(asize << 3), ofmt->shortname);
         } else {
@@ -506,17 +501,17 @@ static void out_segment(struct out_data *data, const struct operand *opx)
     if (opx->opflags & OPFLAG_RELATIVE)
         nasm_nonfatal("segment references cannot be relative");
 
-    data->type = OUT_SEGMENT;
-    data->sign = OUT_UNSIGNED;
-    data->size = 2;
-    data->toffset = opx->offset;
-    data->tsegment = ofmt->segbase(opx->segment | 1);
-    data->twrt = opx->wrt;
+    data->type      = OUT_SEGMENT;
+    data->flags     = OUT_UNSIGNED;
+    data->size      = 2;
+    data->toffset   = opx->offset;
+    data->tsegment  = ofmt->segbase(opx->segment | 1);
+    data->twrt      = opx->wrt;
     out(data);
 }
 
 static void out_imm(struct out_data *data, const struct operand *opx,
-                    int size, enum out_sign sign)
+                    int size, enum out_flags sign)
 {
     if (opx->segment != NO_SEG && (opx->segment & 1)) {
         /*
@@ -531,10 +526,10 @@ static void out_imm(struct out_data *data, const struct operand *opx,
         data->type = (opx->opflags & OPFLAG_RELATIVE)
             ? OUT_RELADDR : OUT_ADDRESS;
     }
-    data->sign = sign;
-    data->toffset = opx->offset;
+    data->flags    = sign;
+    data->toffset  = opx->offset;
     data->tsegment = opx->segment;
-    data->twrt = opx->wrt;
+    data->twrt     = opx->wrt;
     /*
      * XXX: improve this if at some point in the future we can
      * distinguish the subtrahend in expressions like [foo - bar]
@@ -553,13 +548,13 @@ static void out_reladdr(struct out_data *data, const struct operand *opx,
     if (opx->opflags & OPFLAG_RELATIVE)
         nasm_nonfatal("invalid use of self-relative expression");
 
-    data->type = OUT_RELADDR;
-    data->sign = OUT_SIGNED;
-    data->size = size;
-    data->toffset = opx->offset;
+    data->type     = OUT_RELADDR;
+    data->flags    = OUT_SIGNED;
+    data->size     = size;
+    data->toffset  = opx->offset;
     data->tsegment = opx->segment;
-    data->twrt = opx->wrt;
-    data->relbase = data->offset + (data->inslen - data->insoffs);
+    data->twrt     = opx->wrt;
+    data->relbase  = data->offset + (data->inslen - data->insoffs);
     out(data);
 }
 
@@ -660,12 +655,12 @@ static void out_eops(struct out_data *data, const extop *e)
                     data->relbase = 0;
                     if (e->val.num.segment != NO_SEG &&
                         (e->val.num.segment & 1)) {
-                        data->type = OUT_SEGMENT;
-                        data->sign = OUT_UNSIGNED;
+                        data->type  = OUT_SEGMENT;
+                        data->flags = OUT_UNSIGNED;
                     } else {
                         data->type = e->val.num.relative
                             ? OUT_RELADDR : OUT_ADDRESS;
-                        data->sign = OUT_WRAP;
+                        data->flags = OUT_WRAP;
                     }
                     out(data);
                 }
diff --git a/include/nasm.h b/include/nasm.h
index 3c9ce962..e33f41bd 100644
--- a/include/nasm.h
+++ b/include/nasm.h
@@ -111,10 +111,11 @@ enum out_type {
     OUT_REL8ADR
 };
 
-enum out_sign {
-    OUT_WRAP,                   /* Undefined signedness (wraps) */
-    OUT_SIGNED,                 /* Value is signed */
-    OUT_UNSIGNED                /* Value is unsigned */
+enum out_flags {
+    OUT_WRAP     = 0,           /* Undefined signedness (wraps) */
+    OUT_SIGNED   = 1,           /* Value is signed */
+    OUT_UNSIGNED = 2,           /* Value is unsigned */
+    OUT_SIGNMASK = 3            /* Mask for signedness bits */
 };
 
 /*
@@ -126,7 +127,7 @@ struct out_data {
     int64_t offset;             /* Offset within segment */
     int32_t segment;            /* Segment written to */
     enum out_type type;         /* See above */
-    enum out_sign sign;         /* See above */
+    enum out_flags flags;       /* See above */
     int inslen;                 /* Length of instruction */
     int insoffs;                /* Offset inside instruction */
     int bits;                   /* Bits mode of compilation */
@@ -908,7 +909,7 @@ struct ofmt {
      * It is allowed to modify the string it is given a pointer to.
      *
      * It is also allowed to specify a default instruction size for
-     * the segment, by setting `*bits' to 16 or 32. Or, if it
+     * the segment, by setting `*bits' to 16, 32 or 64. Or, if it
      * doesn't wish to define a default, it can leave `bits' alone.
      */
     int32_t (*section)(char *name, int *bits);
diff --git a/output/legacy.c b/output/legacy.c
index 39793205..d2785387 100644
--- a/output/legacy.c
+++ b/output/legacy.c
@@ -90,13 +90,13 @@ void nasm_do_legacy_output(const struct out_data *data)
     case OUT_SEGMENT:
         type = OUT_ADDRESS;
         dptr = zero_buffer;
-        size = (data->sign == OUT_SIGNED) ? -data->size : data->size;
+        size = (data->flags & OUT_SIGNED) ? -data->size : data->size;
         tsegment |= 1;
         break;
 
     case OUT_ADDRESS:
         dptr = &data->toffset;
-        size = (data->sign == OUT_SIGNED) ? -data->size : data->size;
+        size = (data->flags & OUT_SIGNED) ? -data->size : data->size;
         break;
 
     case OUT_RAWDATA:
diff --git a/output/outdbg.c b/output/outdbg.c
index a823fdff..db933294 100644
--- a/output/outdbg.c
+++ b/output/outdbg.c
@@ -181,30 +181,45 @@ static const char *out_type(enum out_type type)
     return out_types[type];
 }
 
-static const char *out_sign(enum out_sign sign)
+static const char *out_flags(enum out_flags flags)
 {
-    static const char *out_signs[] = {
-        "wrap",
+    static const char *out_flags[] = {
         "signed",
         "unsigned"
     };
-    static char invalid_buf[64];
-
-    if (sign >= sizeof(out_signs)/sizeof(out_signs[0])) {
-        sprintf(invalid_buf, "[invalid sign %d]", sign);
-        return invalid_buf;
+    static char flags_buf[1024];
+    unsigned long flv = flags;
+    size_t n;
+    size_t left = sizeof flags_buf - 1;
+    char *p = flags_buf;
+    unsigned int i;
+
+    for (i = 0; flv; flv >>= 1, i++) {
+        if (flv & 1) {
+            if (i < ARRAY_SIZE(out_flags))
+                n = snprintf(p, left, "%s,", out_flags[i]);
+            else
+                n = snprintf(p, left, "%u,", i);
+            if (n >= left)
+                break;
+            left -= n;
+            p += n;
+        }
     }
+    if (p > flags_buf)
+        p--;                    /* Delete final comma */
+    *p = '\0';
 
-    return out_signs[sign];
+    return flags_buf;
 }
 
 static void dbg_out(const struct out_data *data)
 {
     fprintf(ofile,
-            "out to %"PRIx32":%"PRIx64" %s %s bits %d insoffs %d/%d "
+            "out to %"PRIx32":%"PRIx64" %s(%s) bits %d insoffs %d/%d "
             "size %"PRIu64,
             data->segment, data->offset,
-            out_type(data->type), out_sign(data->sign),
+            out_type(data->type), out_flags(data->flags),
             data->bits, data->insoffs, data->inslen, data->size);
     if (data->itemp) {
         fprintf(ofile, " ins %s(%d)",
@@ -521,7 +536,7 @@ const struct ofmt of_dbg = {
     "Trace of all info passed to output stage",
     "dbg",
     ".dbg",
-    OFMT_TEXT,
+    OFMT_TEXT|OFMT_KEEP_ADDR,
     64,
     debug_debug_arr,
     &debug_debug_form,


More information about the Nasm-commits mailing list