lwzu
Load Word and Zero with Update - 84 00 00 00
lwzu

Instruction Syntax

Mnemonic Format Flags
lwzu rD,d(rA) -

Instruction Encoding

1
0
0
0
0
1
D
D
D
D
D
A
A
A
A
A
d
d
d
d
d
d
d
d
d
d
d
d
d
d
d
d

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:

Related Instructions

lwz, lwzx, lwzux, stwu, lbzu, lhzu

Back to Index