Instruction Syntax
| Mnemonic | Format | Flags |
| lwzu | rD,d(rA) | - |
Instruction Encoding
| Field | Bits | Description |
| Primary Opcode | 0-5 | 100001 (0x21) |
| rD | 6-10 | Destination register |
| rA | 11-15 | Source register A |
| d | 16-31 | 16-bit signed displacement |
Operation
EA ← (rA) + EXTS(d) rD ← MEM(EA, 4) rA ← EA
A word (32 bits) is loaded from memory and placed in register rD. The effective address is computed by adding the sign-extended displacement to the contents of register rA. After the load, the effective address is stored back into register rA.
Note: This instruction cannot be used with rA=0. The update form requires a valid base register. The destination register rD can be the same as rA, in which case the loaded data takes precedence over the address update. The effective address should be word-aligned (divisible by 4) for optimal performance.
Affected Registers
rA - Updated with the effective address after the load operation.
For more information on memory addressing see Section 2.1.6, "Effective Address Calculation," in the PowerPC Microprocessor Family: The Programming Environments manual.
Examples
Sequential Word Array Processing
# Process 32-bit integer array with automatic advance
lis r3, int_array@ha
addi r3, r3, int_array@l
lwz r4, array_length(r0) # Number of elements
subi r3, r3, 4 # Pre-adjust for first lwzu
process_loop:
lwzu r5, 4(r3) # Load next integer and advance pointer
# Process integer (e.g., checksum calculation)
lwz r6, running_checksum(r0)
add r7, r6, r5 # Add to checksum
stw r7, running_checksum(r0) # Store updated checksum
subi r4, r4, 1 # Decrement counter
cmpwi r4, 0
bne process_loop # Continue if more elements
Linked List Traversal
# Traverse linked list using update addressing
# Node structure: [data, next_ptr, flags, reserved]
lis r3, list_head@ha
lwz r4, list_head@l(r3) # Load head pointer
subi r4, r4, 4 # Pre-adjust for first lwzu
traverse_list:
cmpwi r4, 0 # Check for null pointer
beq list_end # Branch if end of list
lwzu r5, 4(r4) # Load data and advance to next field
lwzu r6, 4(r4) # Load next_ptr and advance
lwzu r7, 4(r4) # Load flags and advance
lwzu r8, 4(r4) # Load reserved and advance (not used)
# Process node data
bl process_node # Process data in r5
# Check flags for special processing
andi. r9, r7, 0x01 # Check delete flag
bne mark_for_deletion
# Move to next node
mr r4, r6 # Next node pointer
subi r4, r4, 4 # Pre-adjust for lwzu
b traverse_list # Continue traversal
mark_for_deletion:
# Add to deletion list
bl add_to_delete_list
mr r4, r6 # Next node pointer
subi r4, r4, 4 # Pre-adjust for lwzu
b traverse_list
list_end:
Function Call Table Processing
# Process function call table with automatic advance
lis r3, call_table@ha
addi r3, r3, call_table@l
lwz r4, num_functions(r0) # Number of function entries
subi r3, r3, 4 # Pre-adjust pointer
# Call table entry: [function_ptr, param_count, flags, context]
function_loop:
lwzu r5, 4(r3) # Load function pointer and advance
lwzu r6, 4(r3) # Load parameter count and advance
lwzu r7, 4(r3) # Load flags and advance
lwzu r8, 4(r3) # Load context pointer and advance
# Validate function pointer
cmpwi r5, 0
beq skip_function # Skip if null pointer
# Check if function is enabled
andi. r9, r7, 0x01 # Check enabled flag
beq skip_function # Skip if disabled
# Set up function call context
mr r10, r8 # Context pointer
cmpwi r10, 0
beq no_context # Skip context setup if null
bl setup_context # Set up execution context
no_context:
# Call function with parameter count in r6
mtctr r5 # Move function pointer to count register
mr r3, r6 # Pass parameter count as first argument
mr r4, r10 # Pass context as second argument
bctrl # Call function
# Check return value for error handling
cmpwi r3, 0 # Check return code
bne function_error # Handle error if non-zero
skip_function:
subi r4, r4, 1 # Decrement function counter
cmpwi r4, 0
bne function_loop # Continue processing
b call_table_done
function_error:
# Handle function error
bl log_function_error
b skip_function # Continue with next function
call_table_done:
Memory Block Transfer
# Transfer memory blocks using word-aligned updates
lis r3, source_buffer@ha
addi r3, r3, source_buffer@l
lis r4, dest_buffer@ha
addi r4, r4, dest_buffer@l
lwz r5, transfer_size(r0) # Size in words
subi r3, r3, 4 # Pre-adjust source pointer
subi r4, r4, 4 # Pre-adjust dest pointer
transfer_loop:
lwzu r6, 4(r3) # Load word from source and advance
stwu r6, 4(r4) # Store word to dest and advance
subi r5, r5, 1 # Decrement word counter
cmpwi r5, 0
bne transfer_loop # Continue transfer
# Verify transfer integrity (optional)
lis r3, source_buffer@ha
addi r3, r3, source_buffer@l
lis r4, dest_buffer@ha
addi r4, r4, dest_buffer@l
lwz r5, transfer_size(r0) # Reset size
subi r3, r3, 4 # Pre-adjust pointers
subi r4, r4, 4
verify_loop:
lwzu r6, 4(r3) # Load source word and advance
lwzu r7, 4(r4) # Load dest word and advance
cmpw r6, r7 # Compare words
bne transfer_error # Branch if mismatch
subi r5, r5, 1 # Decrement counter
cmpwi r5, 0
bne verify_loop # Continue verification
b transfer_verified
transfer_error:
# Handle transfer error
bl handle_transfer_error
transfer_verified:
Database Record Processing
# Process variable-length database records
lis r3, record_buffer@ha
addi r3, r3, record_buffer@l
lwz r4, buffer_size(r0) # Total buffer size in bytes
subi r3, r3, 4 # Pre-adjust pointer
li r5, 0 # Bytes processed
# Record header: [record_type, record_size, field_count, checksum]
record_loop:
cmpw r5, r4 # Check if processed entire buffer
bge buffer_done # Branch if done
lwzu r6, 4(r3) # Load record type and advance
lwzu r7, 4(r3) # Load record size and advance
lwzu r8, 4(r3) # Load field count and advance
lwzu r9, 4(r3) # Load checksum and advance
# Update bytes processed (4 words = 16 bytes for header)
addi r5, r5, 16
# Validate record
cmpwi r7, 0 # Check for valid size
ble invalid_record # Branch if invalid
cmpwi r7, 1024 # Check maximum size
bgt invalid_record # Branch if too large
# Process record based on type
cmpwi r6, RECORD_CUSTOMER
beq process_customer
cmpwi r6, RECORD_ORDER
beq process_order
cmpwi r6, RECORD_PRODUCT
beq process_product
b skip_record # Unknown record type
process_customer:
# Process customer record fields
mr r10, r8 # Field count
customer_field_loop:
cmpwi r10, 0 # Check if done with fields
beq record_complete
lwzu r11, 4(r3) # Load field value and advance
addi r5, r5, 4 # Update bytes processed
# Process customer field (simplified)
bl process_customer_field
subi r10, r10, 1 # Decrement field count
b customer_field_loop
process_order:
# Process order record
mr r10, r8 # Field count
order_field_loop:
cmpwi r10, 0
beq record_complete
lwzu r11, 4(r3) # Load field value and advance
addi r5, r5, 4 # Update bytes processed
# Process order field
bl process_order_field
subi r10, r10, 1
b order_field_loop
process_product:
# Process product record
mr r10, r8 # Field count
product_field_loop:
cmpwi r10, 0
beq record_complete
lwzu r11, 4(r3) # Load field value and advance
addi r5, r5, 4 # Update bytes processed
# Process product field
bl process_product_field
subi r10, r10, 1
b product_field_loop
skip_record:
# Skip unknown record type
subi r7, r7, 16 # Subtract header size from record size
add r3, r3, r7 # Skip record data
add r5, r5, r7 # Update bytes processed
b record_complete
record_complete:
b record_loop # Process next record
invalid_record:
# Handle invalid record
bl log_invalid_record
# Try to recover by finding next valid record header
bl find_next_record
b record_loop
buffer_done:
Graphics Command Buffer
# Process graphics command buffer with variable-length commands
lis r3, command_buffer@ha
addi r3, r3, command_buffer@l
lwz r4, buffer_end@ha
lwz r5, buffer_end@l(r4) # End of buffer address
subi r3, r3, 4 # Pre-adjust pointer
# Command format: [command_id, param_count, param1, param2, ...]
command_loop:
cmpw r3, r5 # Check if reached end of buffer
bge commands_done # Branch if done
lwzu r6, 4(r3) # Load command ID and advance
lwzu r7, 4(r3) # Load parameter count and advance
# Process command based on ID
cmpwi r6, CMD_DRAW_TRIANGLE
beq draw_triangle
cmpwi r6, CMD_SET_TEXTURE
beq set_texture
cmpwi r6, CMD_SET_MATRIX
beq set_matrix
cmpwi r6, CMD_CLEAR_BUFFER
beq clear_buffer
b unknown_command # Unknown command
draw_triangle:
# Load triangle parameters (9 parameters: 3 vertices * 3 coordinates)
cmpwi r7, 9 # Verify parameter count
bne invalid_params
# Load vertex 1
lwzu r8, 4(r3) # x1
lwzu r9, 4(r3) # y1
lwzu r10, 4(r3) # z1
# Load vertex 2
lwzu r11, 4(r3) # x2
lwzu r12, 4(r3) # y2
lwzu r13, 4(r3) # z2
# Load vertex 3
lwzu r14, 4(r3) # x3
lwzu r15, 4(r3) # y3
lwzu r16, 4(r3) # z3
# Render triangle
bl render_triangle # Pass vertex coordinates
b command_loop
set_texture:
# Load texture parameters
cmpwi r7, 2 # Verify parameter count (texture_id, filter_mode)
bne invalid_params
lwzu r8, 4(r3) # Load texture ID and advance
lwzu r9, 4(r3) # Load filter mode and advance
# Apply texture settings
bl set_active_texture # Pass texture ID and filter mode
b command_loop
set_matrix:
# Load matrix parameters (16 values for 4x4 matrix)
cmpwi r7, 16 # Verify parameter count
bne invalid_params
# Load matrix elements
lis r17, temp_matrix@ha
addi r17, r17, temp_matrix@l
subi r17, r17, 4 # Pre-adjust temp matrix pointer
li r18, 16 # Counter for matrix elements
matrix_load_loop:
lwzu r19, 4(r3) # Load matrix element and advance
stwu r19, 4(r17) # Store in temp matrix and advance
subi r18, r18, 1 # Decrement counter
cmpwi r18, 0
bne matrix_load_loop # Continue loading matrix
# Apply matrix transformation
lis r20, temp_matrix@ha
addi r20, r20, temp_matrix@l
bl set_transformation_matrix # Pass matrix pointer
b command_loop
clear_buffer:
# Load clear parameters
cmpwi r7, 4 # Verify parameter count (R, G, B, A)
bne invalid_params
lwzu r8, 4(r3) # Load red component and advance
lwzu r9, 4(r3) # Load green component and advance
lwzu r10, 4(r3) # Load blue component and advance
lwzu r11, 4(r3) # Load alpha component and advance
# Clear framebuffer
bl clear_framebuffer # Pass RGBA components
b command_loop
unknown_command:
# Skip unknown command by advancing past its parameters
slwi r20, r7, 2 # Convert param count to bytes (param_count * 4)
add r3, r3, r20 # Skip parameters
bl log_unknown_command # Log warning
b command_loop
invalid_params:
# Handle invalid parameter count
bl log_invalid_params
# Skip command by advancing past specified number of parameters
slwi r21, r7, 2 # Convert param count to bytes
add r3, r3, r21 # Skip parameters
b command_loop
commands_done:
Compiler Symbol Table Processing
# Process compiler symbol table during compilation
lis r3, symbol_table@ha
addi r3, r3, symbol_table@l
lwz r4, num_symbols(r0) # Number of symbol entries
subi r3, r3, 4 # Pre-adjust pointer
# Symbol entry: [symbol_id, type, scope, address]
symbol_loop:
lwzu r5, 4(r3) # Load symbol ID and advance
lwzu r6, 4(r3) # Load symbol type and advance
lwzu r7, 4(r3) # Load scope level and advance
lwzu r8, 4(r3) # Load address/offset and advance
# Process symbol based on type
cmpwi r6, SYM_VARIABLE
beq process_variable
cmpwi r6, SYM_FUNCTION
beq process_function
cmpwi r6, SYM_CONSTANT
beq process_constant
cmpwi r6, SYM_TYPE
beq process_type
b unknown_symbol # Unknown symbol type
process_variable:
# Check scope for variable resolution
lwz r9, current_scope(r0)
cmpw r7, r9 # Compare symbol scope with current
bgt out_of_scope # Symbol not accessible
# Add to variable lookup table
bl add_variable_entry # Pass symbol_id, scope, address
# Generate variable access code
bl generate_var_access # Pass address in r8
b next_symbol
process_function:
# Add function to call table
bl add_function_entry # Pass symbol_id, address
# Generate function call stub if needed
andi. r10, r7, SCOPE_EXTERNAL # Check if external function
beq internal_function
bl generate_external_stub # Generate external call stub
b next_symbol
internal_function:
bl generate_internal_call # Generate internal call
b next_symbol
process_constant:
# Add constant to constant pool
bl add_constant_entry # Pass symbol_id, value in r8
# Generate constant load code
bl generate_const_load # Pass constant value
b next_symbol
process_type:
# Add type information to type table
bl add_type_entry # Pass symbol_id, type info
b next_symbol
unknown_symbol:
# Handle unknown symbol type
bl log_unknown_symbol
b next_symbol
out_of_scope:
# Handle out-of-scope symbol reference
bl report_scope_error
b next_symbol
next_symbol:
subi r4, r4, 1 # Decrement symbol counter
cmpwi r4, 0
bne symbol_loop # Continue processing symbols
# Generate final symbol table for linker
bl generate_symbol_table
Network Packet Queue Processing
# Process network packet queue with automatic advancement
lis r3, packet_queue@ha
addi r3, r3, packet_queue@l
lwz r4, queue_size(r0) # Number of packet descriptors
subi r3, r3, 4 # Pre-adjust pointer
# Packet descriptor: [packet_ptr, length, flags, timestamp]
packet_loop:
lwzu r5, 4(r3) # Load packet pointer and advance
lwzu r6, 4(r3) # Load packet length and advance
lwzu r7, 4(r3) # Load flags and advance
lwzu r8, 4(r3) # Load timestamp and advance
# Validate packet
cmpwi r5, 0 # Check for null pointer
beq invalid_packet # Skip if null
cmpwi r6, 0 # Check for valid length
ble invalid_packet # Skip if invalid length
cmpwi r6, MAX_PACKET_SIZE # Check maximum size
bgt invalid_packet # Skip if too large
# Check packet flags
andi. r9, r7, PKT_FLAG_URGENT
bne process_urgent # Handle urgent packets first
andi. r9, r7, PKT_FLAG_ENCRYPTED
bne decrypt_packet # Decrypt if needed
b normal_processing
process_urgent:
# Process urgent packet immediately
bl process_urgent_packet # Pass packet_ptr, length
b packet_processed
decrypt_packet:
# Decrypt packet before processing
bl decrypt_packet_data # Pass packet_ptr, length
# Fall through to normal processing
normal_processing:
# Standard packet processing
bl process_packet # Pass packet_ptr, length
packet_processed:
# Update packet statistics
lwz r10, packets_processed(r0)
addi r11, r10, 1
stw r11, packets_processed(r0)
# Check if packet needs to be freed
andi. r12, r7, PKT_FLAG_STATIC
bne static_packet # Don't free static packets
# Free dynamic packet memory
bl free_packet_memory # Pass packet_ptr
static_packet:
b next_packet
invalid_packet:
# Handle invalid packet
bl log_invalid_packet
# Update error statistics
lwz r13, packet_errors(r0)
addi r14, r13, 1
stw r14, packet_errors(r0)
next_packet:
subi r4, r4, 1 # Decrement packet counter
cmpwi r4, 0
bne packet_loop # Continue processing packets
# Calculate packet processing statistics
lwz r15, packets_processed(r0)
lwz r16, packet_errors(r0)
add r17, r15, r16 # Total packets examined
cmpwi r17, 0
beq no_packets
# Calculate success rate (processed / total * 100)
mulli r18, r15, 100 # processed * 100
divw r19, r18, r17 # (processed * 100) / total
stw r19, success_rate(r0) # Store success rate percentage
no_packets: