Hyde Appendix B
Hyde Appendix B
fro m
ONLINE APPENDIX B
T h e M i n i ma l P o w er P C I n st r u c t i o n S et
b y R anda l l H yde
San Francisco
wgc2_OB_title.fm Page ii Thursday, April 20, 2006 12:27 PM
WRITE GREAT CODE, Volume 2. Copyright © 2006 by Randall Hyde. ISBN 1-59327-065-8.
All Rights Reserved. No part of this work may be reproduced or transmitted in any form or by any means, electronic
or mechanical, including photocopying, recording, or by any information storage or retrieval system, without the
prior written permission of the copyright owner and the publisher.
No Starch Press and the No Starch Press logo are registered trademarks of No Starch Press, Inc. Other product and
company names mentioned herein may be the trademarks of their respective owners. Rather than use a trademark
symbol with every occurrence of a trademarked name, we are using the names only in an editorial fashion and to the
benefit of the trademark owner, with no intention of infringement of the trademark.
For information on book distributors or translations, please contact No Starch Press, Inc. directly:
The information in this online appendix is distributed on an “As Is” basis, without warranty. While every precaution
has been taken in the preparation of this material, neither the author nor No Starch Press, Inc. shall have any liability
to any person or entity with respect to any loss or damage caused or alleged to be caused directly or indirectly by the
information contained in it.
Hyde, Randall.
Write great code : understanding the machine / Randall Hyde.
p. cm.
ISBN 1-59327-003-8
1. Computer programming. 2. Computer architecture. I. Title.
QA76.6.H94 2004
005.1--dc22
2003017502
If you haven’t purchased a copy of Write Great Code, Volume 2: Thinking Low-Level, Writing High-Level and would like to
do so, please go to www.nostarch.com.
wgc2_OB_02.fm Page 1 Thursday, April 20, 2006 12:25 PM
B
THE MINIMAL POWERPC
INSTRUCTION SET
instructions tells the CPU to update the condition-code CR0 bits based on
the result of the operation. An o suffix tells the CPU to update the overflow
and summary overflow bits in the XER register. Finally, an o. suffix tells the
CPU to update the bits in CR0 and the XER register. The following
descriptions group instructions together that differ only by these suffixes.
Instruction Description
add Rd, Rs1, Rs2 Rd := Rs1 + Rs2
d, s1, and s2 are register numbers in the range 0..31.
add. Rd, Rs1, Rs2 Rd := Rs1 + Rs2
CR0 reflects the result of the sum.
d, s1, and s2 are register numbers in the range 0..31.
addo Rd, Rs1, Rs2 Rd := Rs1 + Rs2
The overflow and summary overflow bits in XER are set if a signed
overflow occurs.
d, s1, and s2 are register numbers in the range 0..31.
addo. Rd, Rs1, Rs2 Rd := Rs1 + Rs2
CR0 reflects the result of the sum.
The overflow and summary overflow bits in XER are set if a signed
overflow occurs.
d, s1, and s2 are register numbers in the range 0..31.
Flag Setting
LT Set if the sum (signed) is less than zero.
GT Set if the sum (signed) is greater than zero.
Zero Set if the sum is zero.
SO The summary overflow bit from the XER is copied to this field after computing the sum.
Flag Setting
OV Set if a signed overflow occurred during the execution of the instruction.
SO Set if the SO bit was previously set, or if a signed overflow occurred during the
execution of the instruction.
CA Unaffected
B.2 addi
The addi instruction (add immediate) adds a constant to the contents of a
source register and stores the sum into a destination register. The constant is
limited to a signed 16-bit value (which the instruction sign extends to 32 bits
prior to use). This instruction does not affect any flags or the overflow bit.
The addi instruction treats R0 differently than the other registers. If you
specify R0 as the source register, the addi instruction uses the value zero
rather than the value held in the R0 register. In this case, the addi instruction
acts as a “load immediate with sign extension” instruction (because adding
an immediate constant with zero simply produces that constant). Though
the PowerPC doesn’t have an actual “load immediate” instruction, most
assemblers assemble the li instruction into the addi opcode.
You will also discover that there is no “subtract immediate” instruction,
even though assemblers like Gas support that mnemonic. Gas (and other
PowerPC assemblers) compile a subi instruction into an addi instruction after
negating the immediate operand.
Instruction Description
addi Rd, Rs1, constant Rd := Rs1 + constant
d and s1 are register numbers in the range 0..31.
B.3 addis
The addis instruction (add immediate, shifted) shifts a 16-bit constant to the
left 16 bits, adds this to the value from a source register, and then stores the
sum into a destination register. This instruction does not affect any flags or
the overflow bit.
The addis instruction treats R0 differently than the other registers. If you
specify R0 as the source register, the addi instruction uses the value zero
rather than the value held in the R0 register.
Instruction Description
addis Rd, Rs1, constant Rd := Rs1 + (constant << 16)
d and s1 are register numbers in the range 0..31.
Instruction Description
and Rd, Rs1, Rs2 Rd := Rs1 AND Rs2
d, s1 , and s2 are register numbers in the range 0..31.
and. Rd, Rs1, Rs2 Rd := Rs1 AND Rs2
CR0 reflects the result of the operation.
d, s1 , and s2 are register numbers in the range 0..31.
Flag Setting
LT Set if the result (signed) is less than zero.
GT Set if the result (signed) is greater than zero.
Zero Set if the sum is zero.
SO Unaffected
Instruction Description
andc Rd, Rs1, Rs2 Rd := Rs1 AND (NOT Rs2)
d, s1, and s2 are register numbers in the range 0..31.
andc. Rd, Rs1, Rs2 Rd := Rs1 AND (NOT Rs2)
CR0 reflects the result of the operation.
d, s1, and s2 are register numbers in the range 0..31.
Flag Setting
LT Set if the result (signed) is less than zero.
GT Set if the result (signed) is greater than zero.
Zero Set if the sum is zero.
SO Unaffected
B.6 andi
The andi (and immediate) instruction requires two register operands and a
16-bit constant. This instruction computes the logical (bitwise) AND of the
value in the second (source) register and the constant value and places the
result in the first (destination) register. Note that this instruction always
clears the HO bits of the destination register.
Instruction Description
andi Rd, Rs, constant Rd := Rs AND constant
d and s are register numbers in the range 0..31.
B.7 andis
The andis (and immediate, shifted) instruction requires two register
operands and a 16-bit constant. This instruction shifts the constant to the
left 16 bits, logically ANDs this with the value held in the source register, and
then places the result in the destination register. Note that this instruction
always clears the LO bits of the destination register.
Instruction Description
andis Rd, Rs, constant Rd := Rs AND (constant << 16)
d and s are register numbers in the range 0..31.
B.8 Branches
Standard PowerPC assembly language exposes the numeric encoding of
the opcode in the standard branch mnemonics. If you’re reading arbitrary
PowerPC assembly code, you might have to memorize “magic numbers”
that appear in the operand field of various branch instructions. Fortunately,
IBM has defined a set of “mnemonic synonyms” that use English names
for various numeric encodings. Compilers like GCC typically use the syno-
nyms rather than the numeric forms. In this appendix, I’ll discuss these
“simplified branch mnemonics.” If you encounter weird forms of the
branch instructions, you may want to consult the PowerPC programmer’s
reference guide (i.e., PowerPC Microprocessor Family: The Programmer’s
Reference Guide) for their exact interpretation.
The PowerPC branch instructions provide four basic addressing modes:
relative, absolute, indirect through LINK, and indirect through COUNT.
GCC doesn’t seem to use the absolute addressing mode (it’s useful mainly in
embedded systems where you have good control over the memory map), so
I’ll not consider that form here.
Instruction Description
b target_address NIA := CIA + displacement
NIA is the next instruction address.
CIA is the current instruction address.
displacement is the distance from the current instruction to the
target_address.
Instruction Description
bl target_address LINK := CIA + 4
NIA := CIA + displacement
NIA is the next instruction address.
CIA is the current instruction address.
displacement is the distance from the current instruction to the
target_address .
Instruction Description
blr NIA := LINK
NIA is the next instruction address.
bctr NIA := COUNT
NIA is the next instruction address.
Instruction Description
blt target Branch if less than.
If the LT bit in CR0 is set, then add the 16-bit displacement to the current
instruction address (CIA) to obtain the next instruction address (NIA). Otherwise,
set the NIA to CIA+4.
ble target Branch if less than or equal.
If the LT or EQ bit in CR0 is set, then add the 16-bit displacement to the current
instruction address (CIA) to obtain the next instruction address (NIA). Otherwise,
set the NIA to CIA+4.
beq target Branch if equal.
If the EQ bit in CR0 is set, then add the 16-bit displacement to the current
instruction address (CIA) to obtain the next instruction address (NIA). Otherwise,
set the NIA to CIA+4.
bgt target Branch if greater than.
If the GT bit in CR0 is set, then add the 16-bit displacement to the current
instruction address (CIA) to obtain the next instruction address (NIA). Otherwise,
set the NIA to CIA+4.
bge target Branch if greater than or equal.
If the GT or EQ bit in CR0 is set, then add the 16-bit displacement to the current
instruction address (CIA) to obtain the next instruction address (NIA). Otherwise,
set the NIA to CIA+4.
bnl target Branch if not less than.
Synonym for bge.
bne target Branch if not equal.
If the EQ bit in CR0 is clear, then add the 16-bit displacement to the current
instruction address (CIA) to obtain the next instruction address (NIA). Otherwise,
set the NIA to CIA+4.
Instruction Description
bng target Branch if not greater than.
Synonym for ble.
bso target Branch if summary overflow.
If the SO bit in CR0 is set, then add the 16-bit displacement to the current
instruction address (CIA) to obtain the next instruction address (NIA). Otherwise,
set the NIA to CIA+4.
bns target Branch if not summary overflow.
If the SO bit in CR0 is clear, then add the 16-bit displacement to the current
instruction address (CIA) to obtain the next instruction address (NIA). Otherwise,
set the NIA to CIA+4.
Indirect Branch
B.9 cmp
The cmp instruction compares the signed values in two registers and updates
the bits in one of the condition-code registers to reflect the comparison’s
results. By default, the cmp instruction assumes that you want to use CR0 to
hold the result, though it is possible to specify a different condition-code
register as the target for the comparison operation.
The cmp instruction sets the LT bit in the condition-code register if the
first operand is less than the second operation (using a signed comparison).
It sets the GT bit if the first operand is greater than the second. It sets the EQ
bit if the two register operands hold the same value. This instruction also
copies the summary overflow bit from the XER register into the SO bit of the
condition-code register.
Instruction Description
cmp Rs1, Rs2 CR0 := Rs1 CMP Rs2
s1 and s2 are register numbers in the range 0..31.
Flag Setting
LT Set if the value in Rs1 (signed) is less than Rs2.
GT Set if the value in Rs1 (signed) is greater than Rs2.
Zero Set values in Rs1 and Rs2 are equal.
SO Copied from the SO bit in the XER register.
B.10 cmpi
The cmpi (compare immediate) instruction compares the signed value in a
register against a constant and updates the bits in one of the condition-code
registers. By default, the cmpi instruction assumes that you want to use CR0
to hold the result, though it is possible to specify a different condition-code
register as the target for the comparison operation.
Instruction Description
cmpi Rs, constant CR0 := Rs CMP constant
s is a register number in the range 0..31.
constant is a 16-bit signed constant.
Flag Setting
LT Set if the value in Rs1 (signed) is less than constant .
GT Set Rs’s value (signed) is greater than constant .
Zero Set value in Rs1 is equal to constant .
SO Copied from the SO bit in the XER register.
B.11 cmpl
The cmpl (compare logical) instruction is similar to cmp except that it does
an unsigned comparison rather than a signed comparison. The syntax and
usage is the same (except, of course, that you use the cmpl mnemonic). See
cmp for more details.
B.12 cmpli
The cmpli (compare logical immediate) instruction is similar to cmpi except
it does an unsigned comparison. The syntax and usage is similar to cmpi
except that you use the cmpli mnemonic and the 16-bit constant must be
an unsigned value in the range 0..65,535. See the description of the cmpi
instruction for more details.
Instruction Description
divw Rd, Rs1, Rs2 Rd := Rs1 / Rs2
d , s1, and s2 are register numbers in the range 0..31.
divw. Rd, Rs1, Rs2 Rd := Rs1 / Rs2
CR0 reflects the result of the quotient.
d , s1, and s2 are register numbers in the range 0..31.
Instruction Description
divwo Rd, Rs1, Rs2 Rd := Rs1 / Rs2
The overflow and summary overflow bits in XER are set if an error
occurs.
d , s1, and s2 are register numbers in the range 0..31.
divwo. Rd, Rs1, Rs2 Rd := Rs1 / Rs2
CR0 reflects the result of the quotient.
The overflow and summary overflow bits in XER are set if an error
occurs.
d , s1, and s2 are register numbers in the range 0..31.
Flag Setting
LT Set if the quotient (signed) is less than zero.
GT Set if the quotient (signed) is greater than zero.
Zero Set if the quotient is zero.
SO The summary overflow bit from the XER is copied to this field after computing the sum.
Flag Setting
OV Set if an error (division by zero or overflow) occurred during the execution of the
instruction.
SO Set if the SO bit was previously set, or if a division error occurred during the execution
of the instruction.
CA Unaffected.
Instruction Description
divwu Rd, Rs1, Rs2 Rd := Rs1 / Rs2
d, s1, and s2 are register numbers in the range 0..31.
divwu. Rd, Rs1, Rs2 Rd := Rs1 / Rs2
CR0 reflects the result of the quotient.
d, s1, and s2 are register numbers in the range 0..31.
Instruction Description
divwuo Rd, Rs1, Rs2 Rd := Rs1 / Rs2
The overflow and summary overflow bits in XER are set if an error
occurs.
d, s1, and s2 are register numbers in the range 0..31.
divwuo. Rd, Rs1, Rs2 Rd := Rs1 / Rs2
CR0 reflects the result of the quotient.
The overflow and summary overflow bits in XER are set if an error
occurs.
d, s1, and s2 are register numbers in the range 0..31.
Flag Setting
LT Set if the quotient is less than zero.
GT Set if the quotient is greater than zero.
Zero Set if the quotient is zero.
SO The summary overflow bit from the XER is copied to this field after computing the sum.
Flag Setting
OV Set if an error (division by zero or overflow) occurred during the execution of the
instruction.
SO Set if the SO bit was previously set, or if a division error occurred during the execution
of the instruction.
CA Unaffected.
Instruction Description
equ Rd, Rs1, Rs2 Rd := Rs1 == Rs2
d, s1 , and s2 are register numbers in the range 0..31.
equ. Rd, Rs1, Rs2 Rd := Rs1 == Rs2
CR0 reflects the result of the operation.
d, s1 , and s2 are register numbers in the range 0..31.
Flag Setting
LT Set if the result (signed) is less than zero.
GT Set if the result (signed) is greater than zero.
Zero Set if the sum is zero.
SO Unaffected
Instruction Description
extsb Rd, Rs Rd := signExtend( Rs[0..7] )
d and s are register numbers in the range 0..31.
extsb. Rd, Rs Rd := signExtend( Rs[0..7] )
d and s are register numbers in the range 0..31.
Flag Setting
LT Set if the result (signed) is less than zero.
GT Set if the result (signed) is greater than zero.
Zero Set if the sum is zero.
SO Unaffected
Instruction Description
extsh Rd, Rs Rd := signExtend( Rs[0..15] )
d and s are register numbers in the range 0..31.
extsh. Rd, Rs Rd := signExtend( Rs[0..15] )
d and s are register numbers in the range 0..31.
Flag Setting
LT Set if the result (signed) is less than zero.
GT Set if the result (signed) is greater than zero.
Zero Set if the sum is zero.
SO Unaffected
B.18 la
The la (load address) instruction is a synonym for the addi instruction. This
instruction computes the effective address of a register plus displacement
addressing mode and places the address in a destination register.
Instruction Description
la Rd, disp(Rs) Rd := constant + Rs
d and s are register numbers in the range 0..31.
This instruction is equivalent to:
addi Rd, Rs, constant
Instruction Description
lbz Rd, disp( Rs ) Rd := zeroExtend( mem8[disp + Rs ] )
d and s are register numbers in the range 0..31.
disp is a 16-bit signed constant.
mem8[ -- ] is the byte at the memory address specified by disp + Rs.
If Rs is R0, then this instruction substitutes the value zero for R0.
lbzu Rd, disp( Rs ) Rd := zeroExtend( mem8[disp + Rs ] )
Rs := disp + Rs
d and s are register numbers in the range 0..31.
disp is a 16-bit signed constant.
If Rs is R0, or Rs and Rd are the same, this is an invalid instruction.
lbzx Rd, Rs, Rx Rd := zeroExtend( mem8[ Rs + Rx ] )
d , s, and x are register numbers in the range 0..31.
If Rs is R0, then this instruction uses zero as the value for Rs.
lbzux Rd, Rs, Rx Rd := zeroExtend( mem8[ Rs + Rx ] )
Rs := Rs + Rx
d , s, and x are register numbers in the range 0..31.
If Rs is R0, or Rs and Rd are the same, this is an invalid instruction.
Instruction Description
lha Rd, disp( Rs ) Rd := signExtend( mem16[disp + Rs ] )
d and s are register numbers in the range 0..31.
disp is a 16-bit signed constant.
mem16[ -- ] is the 16-bit halfword at the memory address specified by
disp + Rs.
If Rs is R0, then this instruction substitutes the value zero for R0.
lhau Rd, disp( Rs ) Rd := signExtend( mem16[disp + Rs ] )
Rs := disp + Rs
d and s are register numbers in the range 0..31.
disp is a 16-bit signed constant.
If Rs is R0, or Rs and Rd are the same, this is an invalid instruction.
lhax Rd, Rs, Rx Rd := signExtend( mem16[ Rs + Rx ] )
d , s, and x are register numbers in the range 0..31.
If Rs is R0, then this instruction uses zero as the value for Rs.
lhaux Rd, Rs, Rx Rd := signExtend( mem16[ Rs + Rx ] )
Rs := Rs + Rx
d , s, and x are register numbers in the range 0..31.
If Rs is R0, or Rs and Rd are the same, this is an invalid instruction.
Instruction Description
lhz Rd, disp( Rs ) Rd := zeroExtend( mem16[disp + Rs ] )
d and s are register numbers in the range 0..31.
disp is a 16-bit signed constant.
mem16[ -- ] is the 16-bit halfword at the memory address specified by
disp + Rs.
If Rs is R0, then this instruction substitutes the value zero for R0.
lhzu Rd, disp( Rs ) Rd := zeroExtend( mem16[disp + Rs ] )
Rs := disp + Rs
d and s are register numbers in the range 0..31.
disp is a 16-bit signed constant.
If Rs is R0, or Rs and Rd are the same, this is an invalid instruction.
lhzx Rd, Rs, Rx Rd := zeroExtend( mem16[ Rs + Rx ] )
d , s, and x are register numbers in the range 0..31.
If Rs is R0, then this instruction uses zero as the value for Rs.
lhzux Rd, Rs, Rx Rd := zeroExtend( mem16[ Rs + Rx ] )
Rs := Rs + Rx
d , s, and x are register numbers in the range 0..31.
If Rs is R0, or Rs and Rd are the same, this is an invalid instruction.
B.22 li
The li (load immediate) instruction is a synonym for the addi instruction
with R0 specified as the source register. This instruction loads a sign-
extended 16-bit value into the specified destination register.
Instruction Description
li Rd, constant Rd := constant
d is a register number in the range 0..31.
This instruction is equivalent to:
addi Rd, 0, constant
B.23 lis
The lis instruction (load immediate, shifted) shifts a 16-bit constant to the
left 16 bits and then stores the value into a destination register. This instruc-
tion does not affect any flags or the overflow bit.
Instruction Description
lis Rd, constant Rd := (constant << 16)
d is a register number in the range 0..31.
This instruction is a synonym for:
addis Rd, 0, constant
B.24 lmw
The lmw (load multiple word) loads a group of registers from a contiguous
block of memory. This instruction has two operands: a starting destination
register and a register plus displacement effective memory address. This
instruction loads all the registers from the destination register through R31
starting at the specified memory location. This instruction is quite useful for
saving a batch of scratch-pad registers or for quickly moving blocks of mem-
ory around. Note that the base register used in the memory addressing mode
must not be present in the range of registers loaded by this instruction.
Instruction Description
lmw Rd, disp( Rs ) Rd..R31 := mem32[ disp + Rs ]...
d and s are register numbers in the range 0..31 and s must be less
than d.
disp is a 16-bit signed constant.
mem32[ -- ]... represents n consecutive 32-bit words in memory, where
n = 31 - d + 1
Instruction Description
lwz Rd, disp( Rs ) Rd := mem32[disp + Rs ]
d and s are register numbers in the range 0..31.
disp is a 16-bit signed constant.
mem32[ -- ] is the 32-bit word at the memory address specified by
disp + Rs.
If Rs is R0, then this instruction substitutes the value zero for R0.
lwzu Rd, disp( Rs ) Rd := mem32[disp + Rs]
Rs := disp + Rs
d and s are register numbers in the range 0..31.
disp is a 16-bit signed constant.
If Rs is R0, or Rs and Rd are the same, this is an invalid instruction.
lszx Rd, Rs, Rx Rd := mem32[ Rs + Rx ]
d , s, and x are register numbers in the range 0..31.
If Rs is R0, then this instruction uses zero as the value for Rs.
lwzux Rd, Rs, Rx Rd := mem32[ Rs + Rx ]
Rs := Rs + Rx
d , s, and x are register numbers in the range 0..31.
If Rs is R0, or Rs and Rd are the same, this is an invalid instruction.
B.26 mcrf
The mcrf (move condition register field) instruction moves the data from one
condition-code register field to another condition-code register field.
Instruction Description
mcrf CRd, CRs CRd := CRs
d and s are condition-code register numbers in the range 0..7.
B.27 mcrxr
The mcrxr (move condition register field from XER) instruction copies bits
0..3 of the XER register (the SO, OV, and CA flags, along with a zero bit) into
the specified condition-code register. This instruction also clears bits 0..3 of
the XER register.
Instruction Description
mcrxr CRd CRd := XER[0..3]
d is a condition-code register number in the range 0..7.
Flag Setting
LT SO field from XER
GT OV field from XER
Zero CA field from XER
SO 0
Flag Setting
SO 0
OV 0
CA 0
B.28 mfcr
The mfcr (move from condition register) instruction copies the entire 32-bit
condition-code register into a general-purpose register.
Instruction Description
mfcr Rd Rd := CR[0..7]
d is a general-purpose register number in the range 0..31.
B.29 mfctr
The mfctr (move from COUNT register) instruction copies the contents of
the COUNT register into a general-purpose register.
Instruction Description
mfctr Rd Rd := COUNT
d is a general-purpose register number in the range 0..31.
B.30 mflr
The mflr (move from LINK register) instruction copies the contents of the
LINK register into a general-purpose register.
Instruction Description
mflr Rd Rd := LINK
d is a general-purpose register number in the range 0..31.
B.31 mr
The mr instruction (move register) requires two register operands—a
destination register and a source register. This instruction copies the value
held in the source register to the destination register. Note that this is a
special form of the or instruction that supplies the source register as both
operands for the or instruction. See the or instruction for more details.
Instruction Description
mr Rd, Rs Rd := Rs
d and s are register numbers in the range 0..31.
B.32 mtcrf
The mtcrf (move to condition register fields) instruction copies zero or more
blocks of 4 bits into one of the condition-code fields in the condition-code
register. This instruction has two operands: an 8-bit bitmap that specifies
which condition-code fields to update and a general-purpose 32-bit register.
For each set bit in the bitmap, this instruction copies the corresponding 4
bits in the general-purpose register to the corresponding positions in the
condition-code register. If a bit in the bitmap contains zero, then the
corresponding bits in the condition-code field are unaffected by this
instruction.
Instruction Description
mtcrf bitmap, Rd CRn := Rd[n*4..n*4+3], but only if bitmap[n] == 1
d is a general-purpose register number in the range 0..31.
bitmap is an 8-bit constant.
B.33 mtctr
The mtctr (move to COUNT) instruction copies the value from a general-
purpose integer register to the COUNT register.
Instruction Description
mtctr Rd COUNT := Rd
d is a general-purpose register number in the range 0..31.
B.34 mtlr
The mtlr (move to LINK) instruction copies the value from a general-
purpose integer register to the LINK register.
Instruction Description
mtlr Rd LINK := Rd
d is a general-purpose register number in the range 0..31.
B.35 mtxer
The mtxer (move to XER) instruction copies the value from a general-
purpose integer register to the XER register.
Instruction Description
mtxer Rd XER := Rd
d is a general-purpose register number in the range 0..31.
Instruction Description
mulhw Rd, Rs1, Rs2 Rd := HO32( Rs1 × Rs2 ) (signed)
d, s1, and s2 are register numbers in the range 0..31.
mulhw. Rd, Rs1, Rs2 Rd := HO32( Rs1 × Rs2 ) (signed)
d, s1, and s2 are register numbers in the range 0..31.
This form updates CR0 (see Table B-54).
Flag Setting
LT Set if the signed result is less than zero.
GT Set if the signed result is greater than zero.
Zero Set if the result is equal to zero.
SO Copied from the SO bit in the XER register.
Instruction Description
mulhwu Rd, Rs1, Rs2 Rd := HO32( Rs1 × Rs2 ) (unsigned)
d, s1, and s2 are register numbers in the range 0..31.
mulhwu. Rd, Rs1, Rs2 Rd := HO32( Rs1 × Rs2 ) (unsigned)
d, s1, and s2 are register numbers in the range 0..31.
This form updates CR0 (see Table B-56).
Flag Setting
LT Set if the signed result is less than zero.
GT Set if the signed result is greater than zero.
Zero Set if the result is equal to zero.
SO Copied from the SO bit in the XER register.
B.38 mulli
The mulli (multiply low word, immediate) instruction produces the LO 32
bits of a 32×32 multiply of two registers. It stores the LO 32 bits of the
product in a third register. Note that this instruction is suitable for both
signed and unsigned operands as the LO 32 bits of the product is the same
for both operand types.
Instruction Description
mulli Rd, Rs, constant Rd := Rs × constant
d and s are register numbers in the range 0..31.
constant is a 16-bit signed integer, which this instruction sign extends
to 32 bits before the multiplication occurs.
Instruction Description
mullw Rd, Rs1, Rs2 Rd := Rs1 × Rs2 (LO 32 bits)
d, s1, and s2 are register numbers in the range 0..31.
mullwo Rd, Rs1, Rs2 Rd := Rs1 × Rs2 (LO 32 bits)
d, s1, and s2 are register numbers in the range 0..31.
This form updates XER.
mullw. Rd, Rs1, Rs2 Rd := Rs1 × Rs2 (LO 32 bits)
d, s1, and s2 are register numbers in the range 0..31.
This form updates CR0.
mullwo. Rd, Rs1, Rs2 Rd := Rs1 × Rs2 (LO 32 bits)
d, s1, and s2 are register numbers in the range 0..31.
This form updates XER and CR0.
Flag Setting
LT Set if the signed result is less than zero.
GT Set if the signed result is greater than zero.
Zero Set if the result is equal to zero.
SO Copied from the SO bit in the XER register.
Flag Setting
SO Set if SO was previously set, or the signed result does not fit into 32 bits.
OV Set if the signed result does not fit into 32 bits.
CA Unaffected.
Instruction Description
nand Rd, Rs1, Rs2 Rd := Rs1 NAND Rs2
d, s1, and s2 are register numbers in the range 0..31.
nand. Rd, Rs1, Rs2 Rd := Rs1 NAND Rs2
CR0 reflects the result of the operation.
d, s1, and s2 are register numbers in the range 0..31.
Flag Setting
LT Set if the result (signed) is less than zero.
GT Set if the result (signed) is greater than zero.
Zero Set if the sum is zero.
SO Unaffected.
Instruction Description
neg Rd, Rs Rd := -Rs
d and s are register numbers in the range 0..31.
neg. Rd, Rs Rd := -Rs
CR0 reflects the result of the negation.
d and s are register numbers in the range 0..31.
nego Rd, Rs Rd := -Rs
The overflow and summary overflow bits in XER are set if a signed overflow
occurs (this occurs if you attempt to negate the most negative value).
d and s are register numbers in the range 0..31.
nego. Rd, Rs Rd := Rs
CR0 reflects the result of the sum.
The overflow and summary overflow bits in XER are set if a signed overflow
occurs.
d and s are register numbers in the range 0..31.
Flag Setting
LT Set if the result is less than zero.
GT Set if the result is greater than zero.
Flag Setting
Zero Set if the result is zero.
SO The summary overflow bit from the XER is copied to this field after computing the sum.
Flag Setting
OV Set if a signed overflow occurred during the execution of the instruction. This occurs if
you attempt to negate the most negative value in the two’s complement system
($8000_0000 for 32-bit values).
SO Set if the SO bit was previously set, or if a signed overflow occurred during the
execution of the instruction.
CA Unaffected.
Instruction Description
nor Rd, Rs1, Rs2 Rd := Rs1 NOR Rs2
d, s1 , and s2 are register numbers in the range 0..31.
nor. Rd, Rs1, Rs2 Rd := Rs1 NOR Rs2
CR0 reflects the result of the operation.
d, s1 , and s2 are register numbers in the range 0..31.
Flag Setting
LT Set if the result (signed) is less than zero.
GT Set if the result (signed) is greater than zero.
Zero Set if the sum is zero.
SO Unaffected.
Instruction Description
or Rd, Rs1, Rs2 Rd := Rs1 OR Rs2
d, s1 , and s2 are register numbers in the range 0..31.
or. Rd, Rs1, Rs2 Rd := Rs1 OR Rs2
CR0 reflects the result of the operation.
d, s1 , and s2 are register numbers in the range 0..31.
Flag Setting
LT Set if the result (signed) is less than zero.
GT Set if the result (signed) is greater than zero.
Zero Set if the sum is zero.
SO Unaffected.
Instruction Description
orc Rd, Rs1, Rs2 Rd := Rs1 OR (NOT Rs2)
d, s1 , and s2 are register numbers in the range 0..31.
orc. Rd, Rs1, Rs2 Rd := Rs1 OR (NOT Rs2)
CR0 reflects the result of the operation.
d, s1 , and s2 are register numbers in the range 0..31.
Flag Setting
LT Set if the result (signed) is less than zero.
GT Set if the result (signed) is greater than zero.
Flag Setting
Zero Set if the sum is zero.
SO Unaffected
B.45 ori
The ori (or immediate) instruction requires two register operands and a 16-
bit constant. This instruction logically ORs the constant with the value held
in the source register, and then places the result in the destination register.
Instruction Description
oris Rd, Rs, constant Rd := Rs OR constant
d and s are register numbers in the range 0..31.
B.46 oris
The oris (or immediate, shifted) instruction requires two register operands
and a 16-bit constant. This instruction shifts the constant to the left 16 bits,
logically ORs this with the value held in the source register, and then places
the result in the destination register.
Instruction Description
oris Rd, Rs, constant Rd := Rs OR (constant << 16)
d and s are register numbers in the range 0..31.
Instruction Description
rlwimi Rd,Rs,n,mb,me Rd := (Rd AND mask0( mb..me )) OR
((Rd ROL n) AND mask1( mb..me))
n is a constant specifying the number of bits to rotate in the source
register.
mb and me specify the beginning and ending bit positions for the mask.
mask0( a..b) is a set of zero bits in positions a..b and ones
everywhere else.
mask1( a..b) is a set of one bits in positions a..b and zeros
everywhere else.
d and s are register numbers in the range 0..31.
rlwimi. Rd,Rs,n,mb,me Rd := (Rd AND mask0( mb..me )) OR
((Rd ROL n) AND mask1( mb..me))
CR0 reflects the result of the operation.
n is a constant specifying the number of bits to rotate in the source
register.
mb and me specify the beginning and ending bit positions for the mask.
mask0( a..b) is a set of zero bits in positions a..b and ones
everywhere else.
mask1( a..b) is a set of one bits in positions a..b and zeros
everywhere else.
d and s are register numbers in the range 0..31.
Flag Setting
LT Set if the result (signed) is less than zero.
GT Set if the result (signed) is greater than zero.
Zero Set if the sum is zero.
SO Unaffected
Instruction Description
rlwinm Rd,Rs,n,mb,me Rd := (Rd ROL n) AND mask(mb..me)
n is a constant specifying the number of bits to rotate in the source
register.
mb and me specify the beginning and ending bit positions for the mask.
mask( a..b) is a set of one bits in positions a..b and zeros everywhere
else.
d and s are register numbers in the range 0..31.
rlwinm. Rd,Rs,n,mb,me Rd := (Rd ROL n) AND mask(mb..me)
CR0 reflects the result of the operation.
n is a constant specifying the number of bits to rotate in the source
register.
mb and me specify the beginning and ending bit positions for the mask.
mask( a..b) is a set of one bits in positions a..b and zeros everywhere
else.
d and s are register numbers in the range 0..31.
Flag Setting
LT Set if the result (signed) is less than zero.
GT Set if the result (signed) is greater than zero.
Zero Set if the sum is zero.
SO Unaffected
Instruction Description
rlwnm Rd,Rs,Rc,mb,me Rd := (Rd ROL Rc) AND mask(mb..me)
mb and me specify the beginning and ending bit positions for the mask.
mask( a..b) is a set of one bits in positions a..b and zeros everywhere
else.
d, s, and c are register numbers in the range 0..31.
rlwnm. Rd,Rs,Rc,mb,me Rd := (Rd ROL Rc) AND mask(mb..me)
CR0 reflects the result of the operation.
mb and me specify the beginning and ending bit positions for the mask.
mask( a..b) is a set of one bits in positions a..b and zeros everywhere
else.
d and s are register numbers in the range 0..31.
Flag Setting
LT Set if the result (signed) is less than zero.
GT Set if the result (signed) is greater than zero.
Zero Set if the sum is zero.
SO Unaffected.
Instruction Description
slw Rd,Rs,Rc Rd := (Rs SHL Rc)
d, s, and c are register numbers in the range 0..31.
slw. Rd,Rs,Rc Rd := (Rs SHL Rc)
CR0 reflects the result of the operation.
d, s, and c are register numbers in the range 0..31.
Flag Setting
LT Set if the result (signed) is less than zero.
GT Set if the result (signed) is greater than zero.
Flag Setting
Zero Set if the sum is zero.
SO Unaffected.
Instruction Description
sraw Rd,Rs,Rc Rd := (Rs SHR Rc) (signed)
d, s , and c are register numbers in the range 0..31.
sraw. Rd,Rs,Rc Rd := (Rs SHR Rc) (signed)
CR0 reflects the result of the operation.
d, s , and c are register numbers in the range 0..31.
Flag Setting
LT Set if the result (signed) is less than zero.
GT Set if the result (signed) is greater than zero.
Zero Set if the sum is zero.
SO Unaffected
Instruction Description
srawi Rd,Rs,constant Rd := (Rs SHR constant) (signed)
constant is the number of bits to shift, in the range 0..31.
d and s are register numbers in the range 0..31.
srawi. Rd,Rs,constant Rd := (Rs SHR constant) (signed)
CR0 reflects the result of the operation.
constant is the number of bits to shift, in the range 0..31.
d and s are register numbers in the range 0..31.
Flag Setting
LT Set if the result (signed) is less than zero.
GT Set if the result (signed) is greater than zero.
Zero Set if the sum is zero.
SO Unaffected.
Instruction Description
srw Rd,Rs,Rc Rd := (Rs SHL Rc)
d, s, and c are register numbers in the range 0..31.
srw. Rd,Rs,Rc Rd := (Rs SHL Rc)
CR0 reflects the result of the operation.
d, s, and c are register numbers in the range 0..31.
Flag Setting
LT Set if the result (signed) is less than zero.
GT Set if the result (signed) is greater than zero.
Zero Set if the sum is zero.
SO Unaffected.
Instruction Description
stb Rs, disp( Rb ) mem8[disp + Rb ] := Rd
s and b are register numbers in the range 0..31.
disp is a 16-bit signed constant.
mem8[ -- ] is the byte at the memory address specified by disp + Rb.
If Rb is R0, then this instruction substitutes the value zero for R0.
stbu Rs, disp( Rb ) mem8[disp + Rb ] := Rd
Rs := disp + Rs
s and b are register numbers in the range 0..31.
disp is a 16-bit signed constant.
mem8[ -- ] is the byte at the memory address specified by disp + Rb.
If Rb is R0, then this instruction substitutes the value zero for R0.
stbx Rs, Rb, Rx mem8[ Rb + Rx ] := Rd
s, b , and x are register numbers in the range 0..31.
If Rb is R0, then this instruction uses zero as the value for Rs.
stbux Rd, Rs, Rx mem8[ Rb + Rx ] := Rd
Rb := Rb + Rx
s, b , and x are register numbers in the range 0..31.
If Rb is R0, then this instruction uses zero as the value for Rs.
The sthux (store halfword indexed, with update) is just like sthx except
it also updates the base register with the effective address after moving the
halfword to memory.
Instruction Description
sth Rs, disp( Rb ) mem16[ disp + Rb ] := Rd
s and b are register numbers in the range 0..31.
disp is a 16-bit signed constant.
mem16[ -- ] is the halfword at the memory address specified by
disp + Rb.
If Rb is R0, then this instruction substitutes the value zero for R0.
sthu Rs, disp( Rb ) mem16[ disp + Rb ] := Rd
Rs := disp + Rs
s and b are register numbers in the range 0..31.
disp is a 16-bit signed constant.
mem16[ -- ] is the halfword at the memory address specified by
disp + Rb.
If Rb is R0, then this instruction substitutes the value zero for R0.
sthx Rs, Rb, Rx mem16[ Rb + Rx ] := Rd
s , b, and x are register numbers in the range 0..31.
mem16[ -- ] is the halfword at the memory address specified by Rb + Rx .
If Rb is R0, then this instruction uses zero as the value for Rs.
sthux Rd, Rs, Rx mem16[ Rb + Rx ] := Rd
Rb := Rb + Rx
s , b, and x are register numbers in the range 0..31.
mem16[ -- ] is the halfword at the memory address specified by Rb + Rx .
If Rb is R0, then this instruction uses zero as the value for Rs.
B.56 stmw
The stmw (store multiple words) writes the values in a group of registers to a
contiguous block of memory. This instruction has two operands: a starting
destination register and a register plus displacement effective memory
address. This instruction stores all the register values from the destination
register through R31 starting at the specified memory location. This instruc-
tion is quite useful for saving a batch of scratch-pad registers or for quickly
moving blocks of memory around.
Instruction Description
stmw Rd, disp( Rs ) mem32[ disp + Rs ]... := Rd..R31
d and s are register numbers in the range 0..31 and s must be less
than d.
disp is a 16-bit signed constant.
mem32[ -- ]... represents n consecutive 32-bit words in memory, where
n = 32 - d.
Instruction Description
stw Rs, disp( Rb ) mem32[disp + Rb ] := Rd
s and b are register numbers in the range 0..31.
disp is a 16-bit signed constant.
mem32[ -- ] is the word at the memory address specified by disp + Rb.
If Rb is R0, then this instruction substitutes the value zero for R0.
stwu Rs, disp( Rb ) mem32[disp + Rb ] := Rd
Rs := disp + Rs
s and b are register numbers in the range 0..31.
disp is a 16-bit signed constant.
mem32[ -- ] is the word at the memory address specified by disp + Rb.
If Rb is R0, then this instruction substitutes the value zero for R0.
stwx Rs, Rb, Rx mem32[ Rb + Rx ] := Rd
s, b , and x are register numbers in the range 0..31.
mem32[ -- ] is the word at the memory address specified by Rb + Rx.
If Rb is R0, then this instruction uses zero as the value for Rs.
stwux Rd, Rs, Rx mem32[ Rb + Rx ] := Rd
Rb := Rb + Rx
s, b , and x are register numbers in the range 0..31.
mem23[ -- ] is the word at the memory address specified by Rb + Rx.
If Rb is R0, then this instruction uses zero as the value for Rs.
Instruction Description
sub Rd, Rs1, Rs2 Rd := Rs1 - Rs2
d, s1, and s2 are register numbers in the range 0..31.
sub. Rd, Rs1, Rs2 Rd := Rs1 - Rs2
CR0 reflects the result of the difference.
d, s1, and s2 are register numbers in the range 0..31.
subo Rd, Rs1, Rs2 Rd := Rs1 - Rs2
The overflow and summary overflow bits in XER are set if a signed
overflow occurs.
d, s1, and s2 are register numbers in the range 0..31.
subo. Rd, Rs1, Rs2 Rd := Rs1 - Rs2
CR0 reflects the result of the difference.
The overflow and summary overflow bits in XER are set if a signed
overflow occurs.
d, s1, and s2 are register numbers in the range 0..31.
Flag Setting
LT Set if the sum (signed) is less than zero.
GT Set if the sum (signed) is greater than zero.
Zero Set if the sum is zero.
SO The summary overflow bit from the XER is copied to this field after computing the sum.
Flag Setting
OV Set if a signed overflow occurred during the execution of the instruction.
SO Set if the SO bit was previously set, or if a signed overflow occurred during the
execution of the instruction.
CA Unaffected.
Instruction Description
subf Rd, Rs1, Rs2 Rd := Rs2 - Rs1
d , s1, and s2 are register numbers in the range 0..31.
subf. Rd, Rs1, Rs2 Rd := Rs2 - Rs1
CR0 reflects the result of the difference.
d , s1, and s2 are register numbers in the range 0..31.
subfo Rd, Rs1, Rs2 Rd := Rs2 - Rs1
The overflow and summary overflow bits in XER are set if a signed
overflow occurs.
d , s1, and s2 are register numbers in the range 0..31.
subfo. Rd, Rs1, Rs2 Rd := Rs2 - Rs1
CR0 reflects the result of the difference.
The overflow and summary overflow bits in XER are set if a signed
overflow occurs.
d , s1, and s2 are register numbers in the range 0..31.
Flag Setting
LT Set if the sum (signed) is less than zero.
GT Set if the sum (signed) is greater than zero.
Zero Set if the sum is zero.
SO The summary overflow bit from the XER is copied to this field after computing the sum.
Flag Setting
OV Set if a signed overflow occurred during the execution of the instruction.
SO Set if the SO bit was previously set, or if a signed overflow occurred during the
execution of the instruction.
CA Unaffected
B.60 subi
The subi instruction (subtract immediate) subtracts a constant from the
contents of a source register and stores the difference into a destination
register. The constant is limited to a signed 16-bit value (which the instruc-
tion sign extends to 32 bits prior to use). This instruction does not affect
any flags or the overflow bit.
Instruction Description
subi Rd, Rs1, constant Rd := Rs1 - constant
d and s1 are register numbers in the range 0..31.
This instruction is a synonym for
addi Rd, Rs, -constant.
B.61 subis
The subis instruction (subtract immediate, shifted) shifts a 16-bit constant
to the left 16 bits, subtracts this from the value in a source register, and then
stores the difference into a destination register.
Instruction Description
subis Rd, Rs, constant Rd := Rs - (constant << 16)
d and s are register numbers in the range 0..31.
This instruction is a synonym for
addis Rd, Rs, -constant.
Instruction Description
xor Rd, Rs1, Rs2 Rd := Rs1 XOR Rs2
d, s1 , and s2 are register numbers in the range 0..31.
xor. Rd, Rs1, Rs2 Rd := Rs1 XOR Rs2
CR0 reflects the result of the operation.
d, s1 , and s2 are register numbers in the range 0..31.
Flag Setting
LT Set if the result (signed) is less than zero.
GT Set if the result (signed) is greater than zero.
Zero Set if the sum is zero.
SO Unaffected
B.63 xori
The xori (exclusive-or immediate) instruction requires two register operands
and a 16-bit constant. This instruction logically exclusive-ORs the constant
with the value held in the source register, and then places the result in the
destination register.
Instruction Description
xoris Rd, Rs, constant Rd := Rs XOR constant
d and s are register numbers in the range 0..31.
B.64 xoris
The xoris (exclusive-or immediate, shifted) instruction requires two register
operands and a 16-bit constant. This instruction shifts the constant to the left
16 bits, logically exclusive-ORs this with the value held in the source register,
and then places the result in the destination register.
Instruction Description
xoris Rd, Rs, constant Rd := Rs XOR (constant << 16)
d and s are register numbers in the range 0..31.