scs@mit-math@mit-mc@sri-unix.UUCP (07/22/83)
Anyone who uses any version of unix or one of its derivatives on pdp11's should be aware of a machine dependency in the c run-time long integer division routines. Although the result of the pdp11 div instruction is officially undefined after an error, these routines (ldiv, lrem, aldiv, and alrem) all use the result at one point. The problem crops up at a point where the quotient just computed is expressible in 16 bits, but is greater than 32767 and so not a proper two's complement number. Apparently most 11's put the divisor in the first destination register and leave the second alone, but the 11/23 clears it. A fix is to put a mov r2, r1 before the second div instruction in each of the four routines (ldiv.s, lrem.s, aldiv.s, and alrem.s). They are usually kept in /usr/src/libc/crt . Of course they will have to be re-assembled and put in /lib/libc.a to take advantage of the fix. I haven't tested this fully, but it definitely helps. It would be safest to re-set r0 as well, but I haven't figured out what the algorithm assumes. Steve Summit
scs@mit-math@mit-mc@sri-unix.UUCP (07/22/83)
Sorry about that. The mov r2, r1 belongs after the second div, before the third one.
gwyn@brl-vld@sri-unix.UUCP (07/29/83)
From: Doug Gwyn (VLD/VMB) <gwyn@brl-vld> You have rediscovered a long-known problem with long division support on PDP-11s. I once saw some fixes from Berkeley but those routines had OTHER bugs. System III (USG 3.0) also has the long division bug on newer PDP-11s; I don't know about System V. I have a totally correct (famous last words) set of the PDP-11 C runtime arithmetic routines here at BRL. I don't know who would be the best redistributor, but if you have an urgent need for correct program execution maybe I could mail them to you.