george@idis.UUCP (George Rosenberg) (01/29/84)
If CSO already has UNIX (and presumably a C compiler) working on their one's complement machine (Sperry 1100), then it would seem that the one's complement arithmetic problem has already been successfully addressed. Of course you may on occasion be confronted with a non-portable construct in an existing program, but that problem is not specific to one's complement arithmetic. One way of dealing with one's complement hardware is for the C compiler to normalize the results of arithmetic expressions (i.e. change "~0" to "0"). Since "~0" can no longer be the result of an arithmetic expression, the expression "0 == ~0" would evaluate to "0" (i.e. false). Similarly, "~0" would be true. Below are arithmetic expressions (in the preceding sense). -e e+e e+=e ++e e-e e-=e --e e*e e*=e e++ e/e e/=e e-- e%e e%=e A second way of dealing with one's complement hardware is for the C compiler to use a two's complement representation. It would simulate two's complement behavior with several one's complement instructions. George Rosenberg idis!george
leichter@yale-com.UUCP (Jerry Leichter) (02/01/84)
The PDP-1 is, of course, not the only machine that did one's-complement "right". The CDC 6000 series of machines were one's-complement. Their arithmetic operations were so defined that the result of an operation, neither of whose operands was -0, was guaranteed never to be -0. It turns out, when you sit down and do it, that this is no harder, and requires no more gates, than having it come out the other way; you just have to design your logic with a little care. Even on a properly designed one's-complement machine, you have to be a bit careful. Booleans - typically, -0 is true and 0 is false - are different from integers. It is not useful to test the sign of a Boolean. In fact, on a 6000, if a -0 is in an X register, you can't use the "test for 0" instruction, since it knows that -0 is zero. (In a B register, you compare to B0, which is always +0, and different.) So actually you end up with three classes: Booleans, used as truth values; masks, which come out of logical operations but may get applied to numbers; and numbers. It's quite important to test things in the way appropriate to their class! A nice feature of one's-complement is that negate and complement are identical. This leads to the standard 6000-series code for absolute value: Give a value in an X register, copy it to another X register, arithmetically right shift 59 places, and XOR back to the original register. This requires no branches - slow on a 6000 (and on modern pipelined machines, for about the same reasons) - and can be interleaved with other operations to take advantage of the 6600's multiple functional units. (You can do the same thing in 2's-complement, but it takes an additional instruction: After the XOR of the mask you built, you sub- tract the mask from the original register.) BTW, for properly designed one's-complement adders, the identity for addition is often -0, rather than 0. When added to values other than -0, the two work equally well; but typically -0+0=0 and -0+(-0)=-0. This is the case for the 6000, anyway... -- Jerry decvax!yale-comix!leichter leichter@yale