<!DOCTYPE html>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
  </head>
  <body>
    <p><br>
    </p>
    <div class="moz-cite-prefix">On 11/6/25 9:46 AM, Mark Wielaard via
      Dwarf-discuss wrote:<br>
    </div>
    <blockquote type="cite"
cite="mid:c8ce23b0e943645dcce8e02a0edafa51abb47d0b.camel@klomp.org">
      <pre wrap="" class="moz-quote-pre">Hi Ben,

On Wed, 2025-10-08 at 12:11 -0700, Ben Woodard via Dwarf-discuss wrote:
</pre>
      <blockquote type="cite">
        <pre wrap="" class="moz-quote-pre">This is regarding <a class="moz-txt-link-freetext" href="https://dwarfstd.org/issues/250924.2.html">https://dwarfstd.org/issues/250924.2.html</a>
</pre>
      </blockquote>
      <pre wrap="" class="moz-quote-pre">
This issue was discussed in the 10/27 DWARF committee meeting.

This "simple" proposal uncovered a couple of issues.</pre>
    </blockquote>
    <p>I have certainly been educated by this discussion.</p>
    <p>When I originally submitted the issue my point was just to have
      the spec clarify a point of ambiguity that I saw when reading the
      spec. My suggested solution was basically to follow the current
      behavior of GDB. </p>
    <p>Subsequently we figured out that GDB currently appears to use the
      CU's language to define how to interpret DW_OP_mod and we all
      universally decided that this was practically insane since there
      are so many languages and not all of them have clearly defined
      modulo and remainder operations.</p>
    <p>Other debuggers appear to use the C % operator to implement
      DW_OP_mod. Post C99 C has had a well defined behavior for both
      signed and unsigned values. When DWARF2 was defined back in 1993
      and likely when Michael Eager made the pronouncement that
      DW_OP_mod was only defined for unsigned he was probably thinking
      about the original K&R which said: "<span
        class="markedContent" id="p344R_mc0"><span
style="left: calc(var(--total-scale-factor) *333.54px); top: calc(var(--total-scale-factor) *741.81px); font-size: calc(var(--total-scale-factor) *13.95px); font-family: serif; transform: scaleX(0.840061);"
          role="presentation" dir="ltr">The direction of truncation for</span><span
style="left: calc(var(--total-scale-factor) *510.19px); top: calc(var(--total-scale-factor) *741.81px); font-size: calc(var(--total-scale-factor) *13.95px); font-family: serif;"
          role="presentation" dir="ltr"> </span><span
style="left: calc(var(--total-scale-factor) *513.68px); top: calc(var(--total-scale-factor) *741.81px); font-size: calc(var(--total-scale-factor) *13.95px); font-family: monospace;"
          role="presentation" dir="ltr">/</span><span
style="left: calc(var(--total-scale-factor) *522.05px); top: calc(var(--total-scale-factor) *741.81px); font-size: calc(var(--total-scale-factor) *13.95px); font-family: monospace;"
          role="presentation" dir="ltr"> </span><span
style="left: calc(var(--total-scale-factor) *525.54px); top: calc(var(--total-scale-factor) *741.81px); font-size: calc(var(--total-scale-factor) *13.95px); font-family: serif; transform: scaleX(0.830577);"
          role="presentation" dir="ltr">and the sign </span></span><span
        class="markedContent" id="p347R_mc0"><span
style="left: calc(var(--total-scale-factor) *9.96px); top: calc(var(--total-scale-factor) *28.53px); font-size: calc(var(--total-scale-factor) *13.95px); font-family: serif; transform: scaleX(0.834679);"
          role="presentation" dir="ltr">of the result for</span><span
style="left: calc(var(--total-scale-factor) *96.35px); top: calc(var(--total-scale-factor) *28.53px); font-size: calc(var(--total-scale-factor) *13.95px); font-family: serif;"
          role="presentation" dir="ltr"> </span><span
style="left: calc(var(--total-scale-factor) *99.84px); top: calc(var(--total-scale-factor) *28.53px); font-size: calc(var(--total-scale-factor) *13.95px); font-family: monospace;"
          role="presentation" dir="ltr">%</span><span
style="left: calc(var(--total-scale-factor) *108.21px); top: calc(var(--total-scale-factor) *28.53px); font-size: calc(var(--total-scale-factor) *13.95px); font-family: monospace;"
          role="presentation" dir="ltr"> </span><span
style="left: calc(var(--total-scale-factor) *111.70px); top: calc(var(--total-scale-factor) *28.53px); font-size: calc(var(--total-scale-factor) *13.95px); font-family: serif; transform: scaleX(0.834014);"
          role="presentation" dir="ltr">are machine-dependent for
          negative operands, as is the action taken on overflow or</span><span
style="left: calc(var(--total-scale-factor) *9.96px); top: calc(var(--total-scale-factor) *45.27px); font-size: calc(var(--total-scale-factor) *13.95px); font-family: serif; transform: scaleX(0.841447);"
          role="presentation" dir="ltr"> underflow."</span></span></p>
    <p>I am currently somewhat unconvinced that there is a use case for
      a mathematically defined modulo operator whose domain includes
      floating point numbers. (I could trivially be convinced otherwise
      if someone knows of one.) On the other hand Jakub has presented a
      case where there is a use for a signed remainder operation,
      basically implementing the C % operator. </p>
    <p>I think if I were submitting the issue today given what I now
      know rather than suggesting that DW_OP_mod implement Knuth's
      algorithm, I would have suggested that it follow C99's
      specification of the % operator.</p>
    <blockquote type="cite"
cite="mid:c8ce23b0e943645dcce8e02a0edafa51abb47d0b.camel@klomp.org">
      <pre wrap="" class="moz-quote-pre">While your first suggestion is to extend the DW_OP_mod operation to
floating point types, we didn't really discuss that part because we
first had to grasp with how DW_OP_mod was defined for the generic and
integral types. If we would want to extend DW_OP_mod to work on
floating types it would be good to define the floating operation for
DW_OP_div too. And make DW_OP_div itself more consistent (it currently
says it always does signed division).

I would propose that dealing with floating types be moved into a new
proposal where we look into all operations that are defined for typed
DWARF that are not required to be of integral or generic type.

Then there is the issue of how DW_OP_mod is defined for the generic
type. This is answered fairly simply by 2.5.1.4 "Arithmetic and Logical
Operations":

   If the type of the operands is the generic type, except as otherwise
   specified, the arithmetic operations perform addressing arithmetic, that
   is, unsigned arithmetic that is performed modulo one plus the largest
   representable address.

So DW_OP_mod works on unsigned values for the generic type. And for
unsigned values modulo and remainder are the same.

Which leaves the issue for (integral) types. If those are signed then
the result depends on the definition of (integral) division used. The
wikipedia page lists at least 5 choices for division (truncated,
floored, euclidean, rounded, ceiling). And various programming
languages pick one of these:
<a class="moz-txt-link-freetext" href="https://en.wikipedia.org/wiki/Modulo#In_programming_languages">https://en.wikipedia.org/wiki/Modulo#In_programming_languages</a>

In general people seem to dislike depending on the programming language
in use to define this.

So it was suggested that we explicitly define DW_OP_mod for integral
types as you suggest using floored division. But then also introduce a
new operator DW_OP_rem that uses truncated division. This new operator
should probably explicitly not be used for Call Frame Instructions (see
section 6.4.2) because it is the same as DW_OP_mod for the generic type
(and existing CFI processors won't know about the new operator).</pre>
    </blockquote>
    <p>Given what I now know and the problem that you pointed out with
      CFI. I think that I would suggest:</p>
    <p>Rename DW_OP_mod to DW_OP_rem in DWARF6 and then specify that it
      uses truncated division so that it follows the semantics of C99's
      % operator for signed and unsigned types. This would minimize the
      implementation difficulty for most consumers. This should be
      backward compatible with existing usage because of the
      undocumented limitation on the domain of DW_OP_mod. If people feel
      there is a need, it can also be extended to support floating point
      types. </p>
    <p>Then if the committee feels that it is useful to have a true
      modulo function, they could also add a DW_OP_modulo which uses
      floored division from Knuth.</p>
    <p>-ben</p>
    <blockquote type="cite"
cite="mid:c8ce23b0e943645dcce8e02a0edafa51abb47d0b.camel@klomp.org">
      <pre wrap="" class="moz-quote-pre"></pre>
    </blockquote>
    <blockquote type="cite"
cite="mid:c8ce23b0e943645dcce8e02a0edafa51abb47d0b.camel@klomp.org">
      <pre wrap="" class="moz-quote-pre">

Cheers,

Mark
</pre>
    </blockquote>
  </body>
</html>