Issue 250924.2: DW_OP_mod doesn’t specify which definition of modulo
| Author: | Ben Woodard |
|---|---|
| Champion: | Mark Wielaard |
| Date submitted: | 2025-09-24 |
| Date revised: | 2025-11-24 |
| Date closed: | 2025-11-24 |
| Type: | Clarification |
| Status: | Accepted |
| DWARF version: | 6 |
Background
Evidently, originally DWARF didn’t allow arithmetic operations on (typed) natural or floating point numbers and most uses of the DWARF stack were done with the assumption that the values being acted upon were addresses and so the computation was assumed to be acting upon unsigned numbers.
At some point, DWARF began to allow the arithmetic operations to work on (typed) natural or floating point numbers and several operations were explicitly defined to work over non-integral values. This led to the paragraph in the current DWARF working draft that says in section 2.5.2.4 on page 37 lines 24-27:
Operations other than
DW_OP_abs,DW_OP_div,DW_OP_minus,DW_OP_mul,DW_OP_negandDW_OP_plusrequire integral types of the operand (either integral base type or the generic type). Operations do not cause an exception on overflow.
Unlike all the other arithmetic operations this explicitly limits
DW_OP_mod to integral base types and the generic type. It lumps
DW_OP_mod in with the logical operations. Furthermore, there are
multiple definitions of the modulo operator which vary in how they
handle signed values.
According to the dwarf-discuss archives, this was raised in 2010
and Michael Eager responded that DW_OP_mod used
the modulo algorithm for unsigned arithmetic. However, this decision was
not recorded in the standard. Since that time, consumers have
implemented different implementations of DW_OP_mod.
This proposal seeks to clarify and harmonize the consumer
implementations of the DW_OP_mod operator by defining which
algorithm to use for signed arithmetic as well as decide whether to
define it for floating point numbers.
Proposal
Rename DW_OP_mod to DW_OP_mod_trunc and explicitly define the
algorithm used as using truncated division.
Under 2.5.1.4 Arithmetic and Logical Operations change 5. DW_OP_mod
to DW_OP_mod_trunc. Add at the end of the paragraph: "Use the
following formula for modulo: x mod_trunc y = x − y ×
trunc(x / y)".
Insert 6. DW_OP_mod_floor with the same explanation as
DW_OP_mod_trunc, but using the formula: "x mod_floor y = x − y
× floor(x / y)".
In Table 7.9: DWARF operation encodings change DW_OP_mod to
DW_OP_mod_trunc. Add DW_OP_mod_floor with constant TBA and no. of
operants zero.
6.4.2 Call Frame Instructions. Add DW_OP_mod_floor to the list of
DWARF operators that cannot be used.
Keep the list of operators which do not require integral the
same. DW_OP_mod_trunc and DW_OP_mod_floor are only defined for
integral types, not floating point.
References
From Knuth Section 1.2.4:
If x and y are any real numbers, we define the following binary operation:
x mod y = x − y × floor(x / y), if y ≠ 0; x mod 0 = x.
2025-10-27: Identified the following options:
- Define
DW_OP_modfor unsigned arithmetic only. - Pick one definition to support signed arithmetic
(see Wikipedia article on Modulo):
- Floored (Knuth, typically called modulo)
- Truncated (often called remainder)
- Euclidean (always non-negative, uncommon)
- Rounded (mostly used only for floating-point remainder)
- Define
DW_OP_modto use floored division; addDW_OP_remusing truncated division. - Make it language/target dependent [ruled out by consensus].
Orthogonal:
- Should it/they be defined for floating-point?
- Should operations on the generic type be unsigned?
2025-11-24: Update after vote on naming and proposal for other issues.
- Update background to mention this isn't just about floating point.
- Rename
DW_OP_modtoDW_OP_mod_trunc(but keep constant value) - Define
DW_OP_mod_truncto use truncated division - Add
DW_OP_mod_floor, defined using floored division - Explicitly disallow
DW_OP_mod_floorin CFI - Don't define for zero nominator (like division, expr just errors)
- Don't change the operators that require integral values (won't support floating point for modulo)
2025-11-24: Accepted.