996
|
1
|
|
2 The file syslib_old.i is the version of the system library included
|
|
3 in the original manual. RTFM for descriptions of the routines. Only
|
|
4 minimal changes have been made in the current version, as follows:
|
|
5
|
|
6 1. Someone added
|
|
7 PLEASE KNOCK BEFORE ENTERING
|
|
8 as the first line, presumably to prevent programs from running off the
|
|
9 end and into the first library routine by mistake.
|
|
10
|
|
11 The other two changes are bug fixes. The bugs appear in all copies of
|
|
12 the library that I have, including the manual from Don Woods (via Mike
|
|
13 Ernst) with carriage controls in the first column. Unless a still more
|
|
14 ancient copy of the library can be found (like in the Dead Sea Scrolls,
|
|
15 perhaps?) we have to assume these bugs have been in there from the
|
|
16 beginning, or at least since the library was converted from EBCDIC to
|
|
17 ASCII and incorporated into the manual.
|
|
18
|
|
19 2. Jacob Mandelson found a bug in the 32-bit division routine where a
|
|
20 select (~) had been substituted for a mingle ($) by mistake. This is at
|
|
21 the end of line 229 of syslib_old.i. I have not checked or tested this
|
|
22 correction, but it seems reasonable since select at that position would
|
|
23 be pointless, but mingle is plausible.
|
|
24
|
|
25 3. I have found either two or three bugs in the 32-bit multiplication
|
|
26 routines, depending on how you count. These only affected the overflow
|
|
27 checking, but the effect was that every single call to (1540) or (1549)
|
|
28 would behave as if there were an overflow.
|
|
29
|
|
30 The first is straightforward. The statement
|
|
31 PLEASE DO :1 <- ":3~'#65280$#65280'"$":5~'#652
|
|
32 80$#65280'"
|
|
33 must be changed to
|
|
34 PLEASE DO :1 <- ":3~'#65280$#65280'"$":4~'#652
|
|
35 80$#65280'"
|
|
36 Not only is this the "right thing to do", but the position of this
|
|
37 statement just after :4 has been computed suggests that it was what
|
|
38 the original author intended.
|
|
39
|
|
40 The remaining problems, however, are not so clearly due to typos. The
|
|
41 32-bit multiplication is done by splitting each input into its low and
|
|
42 high 16-bit halves, computing partial products with the (1530) 16 to
|
|
43 32-bit multiplication routine, and then adding them together using
|
|
44 (1509), addition with overflow check. The statements to look at are
|
|
45 the ones where the overflow flags from successive steps are accumulated
|
|
46 in .5, as follows:
|
|
47
|
|
48 [a] DO .5 <- ':1~:1'~#1
|
|
49 ...
|
|
50
|
|
51 [b] PLEASE DO .5 <- '"':1~:1'~#1"$.5'~#3
|
|
52 ...
|
|
53
|
|
54 DO (1509) NEXT
|
|
55 [c] DO .5 <- !5$":4~#3"'~#15
|
|
56 ...
|
|
57
|
|
58 DO (1509) NEXT
|
|
59 [d] PLEASE DO .5 <- !5$":4~#3"'~#63
|
|
60 DO .5 <- '?"!5~.5'~#1"$#1'~#3
|
|
61
|
|
62 .5 gets a bit if the high-high product is nonzero (wasteful to even compute
|
|
63 this product, actually), and another if either of the high-low products
|
|
64 overflows (that's the statement with the previous bug, above). It then
|
|
65 gets combined with the overflow flags in :4 from the two addition calls.
|
|
66 Each new flag is mingled with the ones already in .5, so various bits of
|
|
67 .5 correspond to the different possible overflows. Finally, .5 is tested
|
|
68 to see if it is nonzero, and if so an overflow results.
|
|
69
|
|
70 Note the expressions ":4~#3". :4 is returned by (1509) as #2 if there is
|
|
71 an overflow, #1 if not. It either case a bit is set in .5. This is why
|
|
72 the routines signaled an overflow every time. Note also the ~#63 in line
|
|
73 [d]. At this point the bit representing existence of the high-high
|
|
74 product has shifted out to the 128-bit, so ~#63 will miss it.
|
|
75
|
|
76 I see three ways out, none of which are obviously the author's intent:
|
|
77
|
|
78 (1) At statement [d] the bit pattern is 101011XX, where 1's indicate
|
|
79 overflows and X's are set by (1509) without overflow. If we replace
|
|
80 ~#63 with ~#172 we test exactly the bits we want. This is the one
|
|
81 I've used since it is the minimal change.
|
|
82
|
|
83 (2) If we replace ":4~#3" with ":4~#2" we only have bits set on overflow,
|
|
84 which seems cleaner. The bit pattern is 10001011 so we still can't use
|
|
85 ~#63, we have to use ~#139 or ~#255 or something similar to get all the
|
|
86 bits. Actually, the final selects in lines [b], [c] and [d] are all
|
|
87 superfluous in this case since the bits discarded are all zero and the
|
|
88 selected quantity can be safely assigned to the 16-bit .5.
|
|
89
|
|
90 (3) If we replace ":4~#3" with ":4~#2" and reverse the mingles to look
|
|
91 like '":4~#2"$.5' then the final bit pattern is 10111 and ~#63 will work,
|
|
92 though it is not necessary.
|
|
93
|
|
94 There are other solutions, of course, but I don't see any simpler ones
|
|
95 than these. If you think ":4~#3" accomplishes nothing, so ":4~#2" must be
|
|
96 meant, note that ":4~#3" converts :4 to 16-bit. The original compiler
|
|
97 apparently required arguments to mingle to be 16-bit, whereas I think
|
|
98 the C-INTERCAL compiler only requires them to be less than #0$#256.
|
|
99 ":4$.5" would thus be technically illegal, even though it might work in
|
|
100 C-INTERCAL.
|
|
101
|
|
102 Louis Howell
|
|
103 May 25, 1996
|