Logical Operations for PPC ASM

For ASM Coders who already know the basics.

Chapter 1 Intro; Understanding Binary/Bits

This thread will teach you how to do various logical operations in PowerPC Assembly. Values you see in registers are obviously displayed in Hex. These Hex values are actually in binary, but they are displayed in Hex for ease of use and readability. Binary is the lowest form of programming. Binary values are represented in bits and a bit can only have two possible values: 0 or 1.

For example, let's say r5 has a value 0x12300BCD. Each GPR is 32 bits in length obviously. This means each hex digit represents 4 bits of binary. The value in r5 in binary form is this....

0001 0010 0011 0000 0000 1011 1100 1101

The range of a Hex digit is 0x0 thru 0xF and this can be displayed in binary when the binary representation is split into groups of 4. So this grouping of 4-bits gives you an easy visual represenation of the register's value in binary form. The first bit (also called the sign bit or the most significant bit) is bit 0. The last bit (also called least significant bit) is bit 31.

When a bit's value is '1', that means the bit is flipped High/True. When a bit is '0',that means the bit is flipped Low/False.

Here is a list of all binary to hex digit conversions:

Btw, here's a good online converter (you can swap back & forth) - https://www.rapidtables.com/convert/numb...inary.html

Logical Operations on done on a per bit basis. So let's say we have a value in r3 and we preform a logical operation to the value in r27. Bit 0 of r3 will have a logical operation done in reference to bit 0 of r27. Bit 1 of r3 will have an operation done in reference to bit 1 of r27, and so on and so on.

Chapter 2: Logical OR

Logical ORing is one of the most commonly used logical operations. ORing means if at least value #1 or value #2 is true, then the result is true.

Binary Diagram:

Scaling up from binary to a hex word value, if r3 has a value of 0x00000001, and r27 has a value of 0x80000001, and these two values are OR'd together, it would produce a result of 0x80000001. Confused by this? let's break it down in binary view...

r3 - 0000 0000 0000 0000 0000 0000 0000 0001

r27 - 1000 0000 0000 0000 0000 0000 0000 0001

Using the binary digram provided above, and you preform a logical OR for every bit, then the result in binary is...

1000 0000 0000 0000 0000 0000 0000 0001

This is why the hex result is 0x80000001.

Broadway comes with the following Logical OR instructions (all instructions include a Record feature):

If you recall back from the Assembly Tutorial HERE, you should now have an understanding of why the usage of the lis and ori instructions are preformed to write entire 32-bit (word) values from scratch to a GPR.

You may find yourself in a scenario where you need flip a bit high and not mess with the other bits in a register. Here's an example where we need load a value into a register, flip its bit value high, then store the valueback

A good usage for OR is to check if two separate values are both true to a third value. Example: check if values in r5 and r6 are both equal to the immediate value of 255

Fyi: nop is a simplified mnemonic of ori r0, r0, 0x0000

Fyi: mr rD, rA is a simplified mnemonic of or rD, rA, rA #rA is logically OR'd with itself

Chapter 3: Logical AND

Another commonly used logical operation is AND. AND means if both value#1 and value#2 are true, then the result is true, otherwise the result is always false. Here is a binary diagram for AND~

ANDing operations for Broadway:

ANDing can be a good way to check if certain bits are flipped high. Let's say a r19 has a value and you want to check if bit 30 + bit 31 are both flipped high. If not, take the branch

ANDing is also a useful tool to remove a bit. Remember in the AND diagram above if any bit in the 'bit pair' reference is 0, the result is always 0.

Example of checking if a bit is flipped low in the upper 16 bits of a register. Check if bit 2 is flipped low in r5, temporarily use r0 to place result in. Lower 16 bits don't matter, will be set to null.

Example of checking if bit 21 is flipped low in r5; place result in r0. Upper 16 bits don't matter, will be set to null.

When dealing with needing to flip two seprate bits low, and one bit is in the upper 16 bits, while the other is in the lower 16 bits, you will need to use 'and' because you will be doing a logical AND with an entire 32 (word) value

Example of ANDing r5's value with the value of 0xFFF7DFFF to make sure bits 8 and 18 are set low. Use r30 to set the value in before the ANDing is executed. When ANDing is executed, check if result is 0 (use Record feature), and branch if result does equal 0.

Chapter 4: Other Logical Operations

Broadway also comes with...

nor (includes Record feature)

nand (includes Record feature)

xor (includes Record feature)

xori

xoris

eqv #also known as xnor but you muse use the operand eqv in compilers (includes Record feature)

Logical NOR is the exact opposite of OR. So if any ORing result would be 0, then NOR's result would be 1 and vice versa.

Binary Diagram of NOR

If you logically NOR a value with itself, you will actually just flip every bit to it's opposite value. This is known as a logical NOT. You can use the simplified mnemonic 'not' to preform this type of operation.

Logical NAND is the exact opposite of AND.

Binary Diagram of NAND

Binary Diagram of XOR (Exclusive OR)

Binary Diagram of EQV aka XNOR (Exclusive NOR); it's just the opposite of XOR.

Chapter 5: Conclusion

Here's a good logical operations calculator - https://keisan.casio.com/exec/system/14495408631029

Understanding logical operation instructions is a must if you are working on a code that has a value in a register that uses bits to represent something such as a characters, levels, maps, items, etc. Happy coding!

For ASM Coders who already know the basics.

Chapter 1 Intro; Understanding Binary/Bits

This thread will teach you how to do various logical operations in PowerPC Assembly. Values you see in registers are obviously displayed in Hex. These Hex values are actually in binary, but they are displayed in Hex for ease of use and readability. Binary is the lowest form of programming. Binary values are represented in bits and a bit can only have two possible values: 0 or 1.

For example, let's say r5 has a value 0x12300BCD. Each GPR is 32 bits in length obviously. This means each hex digit represents 4 bits of binary. The value in r5 in binary form is this....

0001 0010 0011 0000 0000 1011 1100 1101

The range of a Hex digit is 0x0 thru 0xF and this can be displayed in binary when the binary representation is split into groups of 4. So this grouping of 4-bits gives you an easy visual represenation of the register's value in binary form. The first bit (also called the sign bit or the most significant bit) is bit 0. The last bit (also called least significant bit) is bit 31.

When a bit's value is '1', that means the bit is flipped High/True. When a bit is '0',that means the bit is flipped Low/False.

Here is a list of all binary to hex digit conversions:

Code:

`0000 = 0x0`

0001 = 0x1

0010 = 0x2

0011 = 0x3

0100 = 0x4

0101 = 0x5

0110 = 0x6

0111 = 0x7

1000 = 0x8

1001 = 0x9

1010 = 0xA

1011 = 0xB

1100 = 0xC

1101 = 0xD

1110 = 0xE

1111 = 0xF

Btw, here's a good online converter (you can swap back & forth) - https://www.rapidtables.com/convert/numb...inary.html

Logical Operations on done on a per bit basis. So let's say we have a value in r3 and we preform a logical operation to the value in r27. Bit 0 of r3 will have a logical operation done in reference to bit 0 of r27. Bit 1 of r3 will have an operation done in reference to bit 1 of r27, and so on and so on.

Chapter 2: Logical OR

Logical ORing is one of the most commonly used logical operations. ORing means if at least value #1 or value #2 is true, then the result is true.

Binary Diagram:

Code:

`Bit Value rA Bit Value rB Bit Result rD`

0 0 0

0 1 1

1 0 1

1 1 1

Scaling up from binary to a hex word value, if r3 has a value of 0x00000001, and r27 has a value of 0x80000001, and these two values are OR'd together, it would produce a result of 0x80000001. Confused by this? let's break it down in binary view...

r3 - 0000 0000 0000 0000 0000 0000 0000 0001

r27 - 1000 0000 0000 0000 0000 0000 0000 0001

Using the binary digram provided above, and you preform a logical OR for every bit, then the result in binary is...

1000 0000 0000 0000 0000 0000 0000 0001

This is why the hex result is 0x80000001.

Broadway comes with the following Logical OR instructions (all instructions include a Record feature):

Code:

`or rD, rA, rB #Value of rA is logically OR'd with value of rB, result placed in rD. This instruction comes with the ability to use the Record feature (free use of cmpwi rD, 0).`

ori rD, rA, VALUE #VALUE is logical/unsigned. rA is OR'd with 0x0000VVVV with VVVV being VALUE, the result is placed in rD.

oris rD, rA, VALUE #VALUE is logical/unsigned; rA is OR'd with 0xVVVV0000 with VVVV being VALUE, the result is placed in rD.

If you recall back from the Assembly Tutorial HERE, you should now have an understanding of why the usage of the lis and ori instructions are preformed to write entire 32-bit (word) values from scratch to a GPR.

You may find yourself in a scenario where you need flip a bit high and not mess with the other bits in a register. Here's an example where we need load a value into a register, flip its bit value high, then store the valueback

Code:

`lwz rX, 0zZZZZ (rY)`

oris rX, rX, 0x8000

stw rX, 0zZZZZ (rY)

A good usage for OR is to check if two separate values are both true to a third value. Example: check if values in r5 and r6 are both equal to the immediate value of 255

Code:

`or r4, r5, r6 #OR r5 with r6, place result temporarily in r4`

cmpwi r4, 255 #Compare result to 255 (0xFF)

beq- some_label #If equal, that means both nummbers in r5 and r6 are 255, take the branch

Fyi: nop is a simplified mnemonic of ori r0, r0, 0x0000

Fyi: mr rD, rA is a simplified mnemonic of or rD, rA, rA #rA is logically OR'd with itself

Chapter 3: Logical AND

Another commonly used logical operation is AND. AND means if both value#1 and value#2 are true, then the result is true, otherwise the result is always false. Here is a binary diagram for AND~

Code:

`Bit Value rA Bit Value rB Bit Result rD`

0 0 0

0 1 0

1 0 0

1 1 1

ANDing operations for Broadway:

Code:

`and rD, rA, rB #rA is AND'd with rB; result in rD. Comes with a Record feature if needed.`

andi. rD, rA, VALUE #VALUE is unsigned; rA is AND'd with 0x0000VVVV with VVVV being VALUE, the result is placed in rD. A form of this instruction w/o the Record feature does NOT exist. The upper 16 bits of rD will always result in 0x0000!

andis. rD, rA, VALUE #VALUE is unsigned; rA is AND'd with 0xVVVV0000 with VVVV being VALUE, the result is placed in rD. A form of this instruction w/o the Record feature does NOT exist. The lower 16 bits of rD will always result in 0x0000!

ANDing can be a good way to check if certain bits are flipped high. Let's say a r19 has a value and you want to check if bit 30 + bit 31 are both flipped high. If not, take the branch

Code:

`andi. r0, r19, 0x0003 #Bits 30 and 31 when flipped high are the hex digit value 3. And 0x3 with r19. Temporarily use r0 to place result in.`

bne- some_label

ANDing is also a useful tool to remove a bit. Remember in the AND diagram above if any bit in the 'bit pair' reference is 0, the result is always 0.

Example of checking if a bit is flipped low in the upper 16 bits of a register. Check if bit 2 is flipped low in r5, temporarily use r0 to place result in. Lower 16 bits don't matter, will be set to null.

Code:

`andis. r0, r5, 0xDFFF #Binary view: 1101 1111 1111 1111; notice bit 2 is set low to force r5's bit 2 to always be low in the result`

Example of checking if bit 21 is flipped low in r5; place result in r0. Upper 16 bits don't matter, will be set to null.

Code:

`andi. r0, r5, 0xFBFF #Binary view 1111 1011 1111 1111`

When dealing with needing to flip two seprate bits low, and one bit is in the upper 16 bits, while the other is in the lower 16 bits, you will need to use 'and' because you will be doing a logical AND with an entire 32 (word) value

Example of ANDing r5's value with the value of 0xFFF7DFFF to make sure bits 8 and 18 are set low. Use r30 to set the value in before the ANDing is executed. When ANDing is executed, check if result is 0 (use Record feature), and branch if result does equal 0.

Code:

`lis r30, 0xFFF7 #Binary view 1111 1111 1111 0111; bit 8 is low`

ori r30, r30, 0xDFFF #Binary view 1101 1111 1111 1111; bit 18 is low

and. r0, r5, r30 #AND r5 and r30, result in r0

beq- some_label

Chapter 4: Other Logical Operations

Broadway also comes with...

nor (includes Record feature)

nand (includes Record feature)

xor (includes Record feature)

xori

xoris

eqv #also known as xnor but you muse use the operand eqv in compilers (includes Record feature)

Logical NOR is the exact opposite of OR. So if any ORing result would be 0, then NOR's result would be 1 and vice versa.

Binary Diagram of NOR

Code:

`Bit Value rA Bit Value rB Bit Result rD`

0 0 1

0 1 0

1 0 0

1 1 0

If you logically NOR a value with itself, you will actually just flip every bit to it's opposite value. This is known as a logical NOT. You can use the simplified mnemonic 'not' to preform this type of operation.

Code:

`not rD, rA = nor rD, rA, rA`

Logical NAND is the exact opposite of AND.

Binary Diagram of NAND

Code:

`Bit Value rA Bit Value rB Bit Result rD`

0 0 1

0 1 1

1 0 1

1 1 0

Binary Diagram of XOR (Exclusive OR)

Code:

`Bit Value rA Bit Value rB Bit Result rD`

0 0 0

0 1 1

1 0 1

1 1 0

Binary Diagram of EQV aka XNOR (Exclusive NOR); it's just the opposite of XOR.

Code:

`Bit Value rA Bit Value rB Bit Result rD`

0 0 1

0 1 0

1 0 0

1 1 1

Chapter 5: Conclusion

Here's a good logical operations calculator - https://keisan.casio.com/exec/system/14495408631029

Understanding logical operation instructions is a must if you are working on a code that has a value in a register that uses bits to represent something such as a characters, levels, maps, items, etc. Happy coding!