FAILURE MAP
← Case archive

FA-89481 / Instruction set emulation / Open access

Signed remainder takes the divisor sign · case 01

rem of a negative dividend by a positive divisor returns a positive remainder.

Verified by executionVariant 1 · 11 checks per implementationDownload source bundle ↓JSON ↗

ROOT CAUSE

The host modulo operator, whose sign follows the divisor, is used.

VERIFIED REPAIR

Compute the remainder as a - q*b with the truncated quotient.

Unsuccessful approach: Using magnitudes loses the dividend sign entirely.

Case contract

Input [op, a, b] with a, b as unsigned 32-bit register values. div/rem interpret them as signed; quotient truncates toward zero and the remainder takes the dividend's sign; division by zero gives quotient all ones (0xFFFFFFFF) and remainder = dividend; the overflow case -2^31 / -1 gives -2^31 with remainder 0. divu/remu are unsigned; divu by zero gives 0xFFFFFFFF and remu by zero gives the dividend. Results are returned as unsigned 32-bit values.

Why this case matters

ISA emulators must reproduce defined results for division corner cases that host languages treat differently or trap on.

1 / The failure

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(*args):
    op, a, b = args
    M = 0xFFFFFFFF
    def s(v):
        return v - (1 << 32) if v >> 31 else v
    if op == 'divu':
        return M if b == 0 else a // b
    if op == 'remu':
        return a if b == 0 else a % b
    sa, sb = s(a), s(b)
    if b == 0:
        return M if op == 'div' else a
    q = abs(sa) // abs(sb)
    if (sa < 0) != (sb < 0):
        q = -q
    if op == 'div':
        return q & M
    return (sa % sb) & M
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('signed division truncates toward zero', ['div', 4294967287, 2], 4294967292), ('signed division negative divisor', ['div', 9, 4294967294], 4294967292), ('signed remainder sign follows dividend', ['rem', 4294967287, 2], 4294967295), ('remainder with negative divisor', ['rem', 9, 4294967294], 1), ('signed divide by zero', ['div', 6, 0], 4294967295), ('signed remainder by zero', ['rem', 4294967286, 0], 4294967286), ('unsigned divide by zero', ['divu', 4, 0], 4294967295), ('unsigned remainder by zero', ['remu', 2147483649, 0], 2147483649), ('unsigned division of high values', ['divu', 4294967279, 3], 1431655759), ('signed overflow case', ['div', 2147483648, 4294967295], 2147483648), ('both negative', ['div', 4294967286, 4294967294], 5)], [('signed division truncates toward zero', ['div', 4294967285, 2], 4294967291), ('signed division negative divisor', ['div', 11, 4294967294], 4294967291), ('signed remainder sign follows dividend', ['rem', 4294967285, 2], 4294967295), ('remainder with negative divisor', ['rem', 11, 4294967294], 1), ('signed divide by zero', ['div', 7, 0], 4294967295), ('signed remainder by zero', ['rem', 4294967285, 0], 4294967285), ('unsigned divide by zero', ['divu', 5, 0], 4294967295), ('unsigned remainder by zero', ['remu', 2147483650, 0], 2147483650), ('unsigned division of high values', ['divu', 4294967278, 3], 1431655759), ('signed overflow case', ['div', 2147483648, 4294967295], 2147483648), ('both negative', ['div', 4294967285, 4294967294], 5)], [('signed division truncates toward zero', ['div', 4294967283, 2], 4294967290), ('signed division negative divisor', ['div', 13, 4294967294], 4294967290), ('signed remainder sign follows dividend', ['rem', 4294967283, 2], 4294967295), ('remainder with negative divisor', ['rem', 13, 4294967294], 1), ('signed divide by zero', ['div', 8, 0], 4294967295), ('signed remainder by zero', ['rem', 4294967284, 0], 4294967284), ('unsigned divide by zero', ['divu', 6, 0], 4294967295), ('unsigned remainder by zero', ['remu', 2147483651, 0], 2147483651), ('unsigned division of high values', ['divu', 4294967277, 3], 1431655759), ('signed overflow case', ['div', 2147483648, 4294967295], 2147483648), ('both negative', ['div', 4294967284, 4294967294], 6)], [('signed division truncates toward zero', ['div', 4294967281, 2], 4294967289), ('signed division negative divisor', ['div', 15, 4294967294], 4294967289), ('signed remainder sign follows dividend', ['rem', 4294967281, 2], 4294967295), ('remainder with negative divisor', ['rem', 15, 4294967294], 1), ('signed divide by zero', ['div', 9, 0], 4294967295), ('signed remainder by zero', ['rem', 4294967283, 0], 4294967283), ('unsigned divide by zero', ['divu', 7, 0], 4294967295), ('unsigned remainder by zero', ['remu', 2147483652, 0], 2147483652), ('unsigned division of high values', ['divu', 4294967276, 3], 1431655758), ('signed overflow case', ['div', 2147483648, 4294967295], 2147483648), ('both negative', ['div', 4294967283, 4294967294], 6)], [('signed division truncates toward zero', ['div', 4294967279, 2], 4294967288), ('signed division negative divisor', ['div', 17, 4294967294], 4294967288), ('signed remainder sign follows dividend', ['rem', 4294967279, 2], 4294967295), ('remainder with negative divisor', ['rem', 17, 4294967294], 1), ('signed divide by zero', ['div', 10, 0], 4294967295), ('signed remainder by zero', ['rem', 4294967282, 0], 4294967282), ('unsigned divide by zero', ['divu', 8, 0], 4294967295), ('unsigned remainder by zero', ['remu', 2147483653, 0], 2147483653), ('unsigned division of high values', ['divu', 4294967275, 3], 1431655758), ('signed overflow case', ['div', 2147483648, 4294967295], 2147483648), ('both negative', ['div', 4294967282, 4294967294], 7)]]
for label, args, expected in fixtures[N-1]:
    check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
signed division truncates toward zero42949672924294967292Passed
signed division negative divisor42949672924294967292Passed
signed remainder sign follows dividend14294967295Failed
remainder with negative divisor42949672951Failed
signed divide by zero42949672954294967295Passed
signed remainder by zero42949672864294967286Passed
unsigned divide by zero42949672954294967295Passed
unsigned remainder by zero21474836492147483649Passed
unsigned division of high values14316557591431655759Passed
signed overflow case21474836482147483648Passed
both negative55Passed

SHA-256 / 04fff84295aaad2d7488cd9530c093a2b02f8250bbb384f395c84be0cc8dca06

2 / The unsuccessful fix

Exit 1
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(*args):
    op, a, b = args
    M = 0xFFFFFFFF
    def s(v):
        return v - (1 << 32) if v >> 31 else v
    if op == 'divu':
        return M if b == 0 else a // b
    if op == 'remu':
        return a if b == 0 else a % b
    sa, sb = s(a), s(b)
    if b == 0:
        return M if op == 'div' else a
    q = abs(sa) // abs(sb)
    if (sa < 0) != (sb < 0):
        q = -q
    if op == 'div':
        return q & M
    return (abs(sa) % abs(sb)) & M
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('signed division truncates toward zero', ['div', 4294967287, 2], 4294967292), ('signed division negative divisor', ['div', 9, 4294967294], 4294967292), ('signed remainder sign follows dividend', ['rem', 4294967287, 2], 4294967295), ('remainder with negative divisor', ['rem', 9, 4294967294], 1), ('signed divide by zero', ['div', 6, 0], 4294967295), ('signed remainder by zero', ['rem', 4294967286, 0], 4294967286), ('unsigned divide by zero', ['divu', 4, 0], 4294967295), ('unsigned remainder by zero', ['remu', 2147483649, 0], 2147483649), ('unsigned division of high values', ['divu', 4294967279, 3], 1431655759), ('signed overflow case', ['div', 2147483648, 4294967295], 2147483648), ('both negative', ['div', 4294967286, 4294967294], 5)], [('signed division truncates toward zero', ['div', 4294967285, 2], 4294967291), ('signed division negative divisor', ['div', 11, 4294967294], 4294967291), ('signed remainder sign follows dividend', ['rem', 4294967285, 2], 4294967295), ('remainder with negative divisor', ['rem', 11, 4294967294], 1), ('signed divide by zero', ['div', 7, 0], 4294967295), ('signed remainder by zero', ['rem', 4294967285, 0], 4294967285), ('unsigned divide by zero', ['divu', 5, 0], 4294967295), ('unsigned remainder by zero', ['remu', 2147483650, 0], 2147483650), ('unsigned division of high values', ['divu', 4294967278, 3], 1431655759), ('signed overflow case', ['div', 2147483648, 4294967295], 2147483648), ('both negative', ['div', 4294967285, 4294967294], 5)], [('signed division truncates toward zero', ['div', 4294967283, 2], 4294967290), ('signed division negative divisor', ['div', 13, 4294967294], 4294967290), ('signed remainder sign follows dividend', ['rem', 4294967283, 2], 4294967295), ('remainder with negative divisor', ['rem', 13, 4294967294], 1), ('signed divide by zero', ['div', 8, 0], 4294967295), ('signed remainder by zero', ['rem', 4294967284, 0], 4294967284), ('unsigned divide by zero', ['divu', 6, 0], 4294967295), ('unsigned remainder by zero', ['remu', 2147483651, 0], 2147483651), ('unsigned division of high values', ['divu', 4294967277, 3], 1431655759), ('signed overflow case', ['div', 2147483648, 4294967295], 2147483648), ('both negative', ['div', 4294967284, 4294967294], 6)], [('signed division truncates toward zero', ['div', 4294967281, 2], 4294967289), ('signed division negative divisor', ['div', 15, 4294967294], 4294967289), ('signed remainder sign follows dividend', ['rem', 4294967281, 2], 4294967295), ('remainder with negative divisor', ['rem', 15, 4294967294], 1), ('signed divide by zero', ['div', 9, 0], 4294967295), ('signed remainder by zero', ['rem', 4294967283, 0], 4294967283), ('unsigned divide by zero', ['divu', 7, 0], 4294967295), ('unsigned remainder by zero', ['remu', 2147483652, 0], 2147483652), ('unsigned division of high values', ['divu', 4294967276, 3], 1431655758), ('signed overflow case', ['div', 2147483648, 4294967295], 2147483648), ('both negative', ['div', 4294967283, 4294967294], 6)], [('signed division truncates toward zero', ['div', 4294967279, 2], 4294967288), ('signed division negative divisor', ['div', 17, 4294967294], 4294967288), ('signed remainder sign follows dividend', ['rem', 4294967279, 2], 4294967295), ('remainder with negative divisor', ['rem', 17, 4294967294], 1), ('signed divide by zero', ['div', 10, 0], 4294967295), ('signed remainder by zero', ['rem', 4294967282, 0], 4294967282), ('unsigned divide by zero', ['divu', 8, 0], 4294967295), ('unsigned remainder by zero', ['remu', 2147483653, 0], 2147483653), ('unsigned division of high values', ['divu', 4294967275, 3], 1431655758), ('signed overflow case', ['div', 2147483648, 4294967295], 2147483648), ('both negative', ['div', 4294967282, 4294967294], 7)]]
for label, args, expected in fixtures[N-1]:
    check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
signed division truncates toward zero42949672924294967292Passed
signed division negative divisor42949672924294967292Passed
signed remainder sign follows dividend14294967295Failed
remainder with negative divisor11Passed
signed divide by zero42949672954294967295Passed
signed remainder by zero42949672864294967286Passed
unsigned divide by zero42949672954294967295Passed
unsigned remainder by zero21474836492147483649Passed
unsigned division of high values14316557591431655759Passed
signed overflow case21474836482147483648Passed
both negative55Passed

SHA-256 / 185fca9ec86a794852418cdaee34186521a75b2616fde42c0fd28d80ba80f36d

3 / The verified repair

Exit 0
"""Failure Map reference implementation. Python standard library only."""
import json

N = 1
observations = []
def solve(*args):
    op, a, b = args
    M = 0xFFFFFFFF
    def s(v):
        return v - (1 << 32) if v >> 31 else v
    if op == 'divu':
        return M if b == 0 else a // b
    if op == 'remu':
        return a if b == 0 else a % b
    sa, sb = s(a), s(b)
    if b == 0:
        return M if op == 'div' else a
    q = abs(sa) // abs(sb)
    if (sa < 0) != (sb < 0):
        q = -q
    if op == 'div':
        return q & M
    return (sa - q * sb) & M
def check(label, actual, expected):
    observations.append({"check": label, "actual": actual, "expected": expected, "passed": actual == expected})
fixtures = [[('signed division truncates toward zero', ['div', 4294967287, 2], 4294967292), ('signed division negative divisor', ['div', 9, 4294967294], 4294967292), ('signed remainder sign follows dividend', ['rem', 4294967287, 2], 4294967295), ('remainder with negative divisor', ['rem', 9, 4294967294], 1), ('signed divide by zero', ['div', 6, 0], 4294967295), ('signed remainder by zero', ['rem', 4294967286, 0], 4294967286), ('unsigned divide by zero', ['divu', 4, 0], 4294967295), ('unsigned remainder by zero', ['remu', 2147483649, 0], 2147483649), ('unsigned division of high values', ['divu', 4294967279, 3], 1431655759), ('signed overflow case', ['div', 2147483648, 4294967295], 2147483648), ('both negative', ['div', 4294967286, 4294967294], 5)], [('signed division truncates toward zero', ['div', 4294967285, 2], 4294967291), ('signed division negative divisor', ['div', 11, 4294967294], 4294967291), ('signed remainder sign follows dividend', ['rem', 4294967285, 2], 4294967295), ('remainder with negative divisor', ['rem', 11, 4294967294], 1), ('signed divide by zero', ['div', 7, 0], 4294967295), ('signed remainder by zero', ['rem', 4294967285, 0], 4294967285), ('unsigned divide by zero', ['divu', 5, 0], 4294967295), ('unsigned remainder by zero', ['remu', 2147483650, 0], 2147483650), ('unsigned division of high values', ['divu', 4294967278, 3], 1431655759), ('signed overflow case', ['div', 2147483648, 4294967295], 2147483648), ('both negative', ['div', 4294967285, 4294967294], 5)], [('signed division truncates toward zero', ['div', 4294967283, 2], 4294967290), ('signed division negative divisor', ['div', 13, 4294967294], 4294967290), ('signed remainder sign follows dividend', ['rem', 4294967283, 2], 4294967295), ('remainder with negative divisor', ['rem', 13, 4294967294], 1), ('signed divide by zero', ['div', 8, 0], 4294967295), ('signed remainder by zero', ['rem', 4294967284, 0], 4294967284), ('unsigned divide by zero', ['divu', 6, 0], 4294967295), ('unsigned remainder by zero', ['remu', 2147483651, 0], 2147483651), ('unsigned division of high values', ['divu', 4294967277, 3], 1431655759), ('signed overflow case', ['div', 2147483648, 4294967295], 2147483648), ('both negative', ['div', 4294967284, 4294967294], 6)], [('signed division truncates toward zero', ['div', 4294967281, 2], 4294967289), ('signed division negative divisor', ['div', 15, 4294967294], 4294967289), ('signed remainder sign follows dividend', ['rem', 4294967281, 2], 4294967295), ('remainder with negative divisor', ['rem', 15, 4294967294], 1), ('signed divide by zero', ['div', 9, 0], 4294967295), ('signed remainder by zero', ['rem', 4294967283, 0], 4294967283), ('unsigned divide by zero', ['divu', 7, 0], 4294967295), ('unsigned remainder by zero', ['remu', 2147483652, 0], 2147483652), ('unsigned division of high values', ['divu', 4294967276, 3], 1431655758), ('signed overflow case', ['div', 2147483648, 4294967295], 2147483648), ('both negative', ['div', 4294967283, 4294967294], 6)], [('signed division truncates toward zero', ['div', 4294967279, 2], 4294967288), ('signed division negative divisor', ['div', 17, 4294967294], 4294967288), ('signed remainder sign follows dividend', ['rem', 4294967279, 2], 4294967295), ('remainder with negative divisor', ['rem', 17, 4294967294], 1), ('signed divide by zero', ['div', 10, 0], 4294967295), ('signed remainder by zero', ['rem', 4294967282, 0], 4294967282), ('unsigned divide by zero', ['divu', 8, 0], 4294967295), ('unsigned remainder by zero', ['remu', 2147483653, 0], 2147483653), ('unsigned division of high values', ['divu', 4294967275, 3], 1431655758), ('signed overflow case', ['div', 2147483648, 4294967295], 2147483648), ('both negative', ['div', 4294967282, 4294967294], 7)]]
for label, args, expected in fixtures[N-1]:
    check(label, solve(*args), expected)
print(json.dumps({"observations": observations, "passed": all(x["passed"] for x in observations)}, ensure_ascii=False))
raise SystemExit(0 if all(x["passed"] for x in observations) else 1)
Boundary fixtureActualExpectedOutcome
signed division truncates toward zero42949672924294967292Passed
signed division negative divisor42949672924294967292Passed
signed remainder sign follows dividend42949672954294967295Passed
remainder with negative divisor11Passed
signed divide by zero42949672954294967295Passed
signed remainder by zero42949672864294967286Passed
unsigned divide by zero42949672954294967295Passed
unsigned remainder by zero21474836492147483649Passed
unsigned division of high values14316557591431655759Passed
signed overflow case21474836482147483648Passed
both negative55Passed

SHA-256 / 3bf675347c0be212f7e143bdc9f7a017a06adaaf9b359566a7f452a4ad6b794c

Verification & scope

A deterministic bounded teaching model of one emulator rule; the instruction semantics are a stipulated contract inspired by common ISAs and are not a claim of cycle-exact or architectural conformance. This reproducer isolates one failure mechanism. Results cover the supplied fixtures. Variants within a family share a test contract and should remain grouped when constructing evaluation splits. Related mechanisms with a shared evaluation_group must also remain together; these controlled models are not independent production incidents.

Observations recorded using Python 3.12.14 at 2026-09-29T14:51:17.890955+00:00.

Case digest / cd95e4945b71fee753b6cf5dc9a1046c37a8710cd8b51b924151962c1cbdb643