简体   繁体   中英

Fastest way to copy sign value among 68k data registers. (Branchless conditional negation of an integer)

I'm looking for an optimized way to change the sign of a value contained in a Data Register using the sign from a value in another Data Register.

Source register will contain either 1 or -1 and destination be always positive therefore all is needed is multiplication. Here's some pseudo code of what I'd do:

MOVE.B #-1,D0
MOVE.W #173,D1
MULS.W D0,D1

After that simple math D1 would carry the sign from D0 and become either -173 or 173. Which is the desired result but MULS takes up to 70 cycles and I'm hoping to save some by finding a trick to somehow only "copy" the sign.

Last word: trick should be branchless as branching is what I'm trying to prevent by copying the sign in the first place.

Thanks in advance for any information or advice.

You could branchlessly select between x and -x , using a bit-hack.

But you can do better: 2's complement negation can be expressed as -x == ~x + 1 , and both the NOT and increment can be expressed in terms of XOR and SUB with -1 . But the same operations with a 0 are no-ops, leaving the value unchanged.

(This trick is often used for 2's complement absolute value, where the 0 or -1 is obtained from arithmetic right shift, x >> 31 , to copy the sign bit to all bits of a register. ie applying your conditional-sign-flip operation to the same number that gave us the sign bit. https://graphics.stanford.edu/~seander/bithacks.html#IntegerAbs )

(TODO: finish this answer with actual 68k XOR and SUB instructions, and a right shift to obtain 0 / -1 from your 1 / -1 input.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM