View Single Post
Old 12 December 2020, 00:10   #187
jotd
This cat is no more
 
jotd's Avatar
 
Join Date: Dec 2004
Location: FRANCE
Age: 52
Posts: 8,309
anyone took a look at this old page?

https://web.archive.org/web/20040905...ldin/main.html

algorithm

Code:
signum(x)
if x > 0 then return 1
else if x < 0 then return -1
else return 0
there's some optimization of signum which is baffling (and also computed automatically!). I think this is 68000

(x in D0)

Code:
ADD.L             D0,D0              (Add D0 to itself)
SUBX.L           D1,D1              (Subtract (D1 + Carry) from D1)
NEGX.L           D0                   (Put (0 – D0 – Carry) into D0)
ADDX.L           D1,D1              (Add (D1 + Carry) to D1
(signum(x) is now in D1)

Quote:
At first glimpse, this makes absolutely no sense. Most glaringly, there are no conditional jumps, while the original code was made of nothing but conditional jumps. Some closer analysis reveals what is actually going on.


ADD.L D0,D0 doubles D0. This is unimportant, as it will not be referenced again, but it takes advantage of a peculiarity of 2’s-complement notation, which is used to store number in registers in binary. Any negative number will be stored as a bit string beginning with 1; thus, when it is doubled, it will overflow, and the carry bit on the processor will be set. SUBX.L D1,D1 clears D1 (by subtracting it from itself), then subtracts the carry bit from it. Since this was set by the previous instruction, D1 is now -1 if the original number was negative, and 0 otherwise. NEGX.L D0 negates D0, which is not important, and sets the carry bit to 1 if and only if D0 was not originally equal to zero. ADDX.L D1,D1 now puts this entire process together by adding D1 to itself, then adding the carry bit. If D0 was originally positive, D1 will be zero and the carry bit will be set. Thus, 0 + 0 + 1 = 1, and D1 will contain 1. If D0 was equal to zero, D1 will be equal to zero and the carry bit will not be set, so 0 + 0 + 0 =0. If D0 was negative, D1 will equal -1 and the carry bit will be set, so -1 + -1 + 1 = -1.

This code is bizarre in ways rarely seen, and would be nearly unreadable to anyone who did not know what was going on. Yet, it works every time, and is considerably faster than the original. Other code fragments generated by Superoptimizer as just as cryptic, but always work perfectly and more efficiently than their predecessors.
Seems that an automated way of doing this is possible. If it is and there's a 68k version somewhere, it could be very interesting for our old machines...
jotd is online now  
 
Page generated in 0.04753 seconds with 11 queries