641

**ROM Hacking Discussion / Re: bad coding in roms**

« **on:**December 18, 2012, 02:08:38 am »

examples:

x = 0 = 0x00000000

temp = x >> 31 = 0x00000000

x^temp-temp = (0^0)-0 = 0-0 = 0

x = 1 = 0x00000001

temp = x >> 31 = 0x00000000

(x^temp)-temp = (1^0)-0 = 1-0 = 1

x = -1 = 0xFFFFFFFF

temp = x >> 31 = 0xFFFFFFFF

(x^temp)-temp = (0xFFFFFFFF^0xFFFFFFFF)-0xFFFFFFFF = 0-(-1) = 1

x = -3 = 0xFFFD

temp = x >> 15 = 0xFFFF

(x^temp)-temp = (0xFFFD^0xFFFF)-0xFFFF = 0x0002-(-1) = 3

^ is a bitwise XOR in C, in case that isn’t clear.

Basically, it all works off several ideas:

- To negate a number in two’s complement, you flip the bits and add 1.

- XOR changes a value if you mask with a 1, and leaves alone if you mask with a 0.

- For a non-negative number, shift-extending the sign bit throughout all bits gives you a mask of all zeroes or ones

- Thus, XORing all bits in a number with its sign bits will flip the bits if the number is negative, and let it be otherwise

- Subtracting by negative one is the same as adding by negative one; adding zero wastes a little time but hurts nothing.

- You’re only bothering to do these extra operations because the time cost is peanuts compared to what branching might do. In general, on modern pipelining / branch-predicting architectures, it is worth replacing a single if statement with a couple of arithmetic statements if you can manage it.

x = 0 = 0x00000000

temp = x >> 31 = 0x00000000

x^temp-temp = (0^0)-0 = 0-0 = 0

x = 1 = 0x00000001

temp = x >> 31 = 0x00000000

(x^temp)-temp = (1^0)-0 = 1-0 = 1

x = -1 = 0xFFFFFFFF

temp = x >> 31 = 0xFFFFFFFF

(x^temp)-temp = (0xFFFFFFFF^0xFFFFFFFF)-0xFFFFFFFF = 0-(-1) = 1

x = -3 = 0xFFFD

temp = x >> 15 = 0xFFFF

(x^temp)-temp = (0xFFFD^0xFFFF)-0xFFFF = 0x0002-(-1) = 3

^ is a bitwise XOR in C, in case that isn’t clear.

Basically, it all works off several ideas:

- To negate a number in two’s complement, you flip the bits and add 1.

- XOR changes a value if you mask with a 1, and leaves alone if you mask with a 0.

- For a non-negative number, shift-extending the sign bit throughout all bits gives you a mask of all zeroes or ones

- Thus, XORing all bits in a number with its sign bits will flip the bits if the number is negative, and let it be otherwise

- Subtracting by negative one is the same as adding by negative one; adding zero wastes a little time but hurts nothing.

- You’re only bothering to do these extra operations because the time cost is peanuts compared to what branching might do. In general, on modern pipelining / branch-predicting architectures, it is worth replacing a single if statement with a couple of arithmetic statements if you can manage it.