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: