[net.arch] One"s complement machines and C logic

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