Instruction Syntax
Mnemonic | Format | Flags |
lhzu | rD,d(rA) | - |
Instruction Encoding
Field | Bits | Description |
Primary Opcode | 0-5 | 101001 (0x29) |
rD | 6-10 | Destination register |
rA | 11-15 | Source register A |
d | 16-31 | 16-bit signed displacement |
Operation
EA ← (rA) + EXTS(d) rD ← 0x0000 || MEM(EA, 2) rA ← EA
A halfword (16 bits) is loaded from memory and placed in the low-order 16 bits of register rD. The upper 16 bits of rD are set to zero. 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.
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 Halfword Processing
# Process 16-bit values in sequence using update form lis r3, data_buffer@ha addi r3, r3, data_buffer@l li r4, 20 # Number of halfwords to process subi r3, r3, 2 # Pre-adjust for first lhzu process_loop: lhzu r5, 2(r3) # Load next halfword and advance pointer # Process halfword in r5 bl process_halfword subi r4, r4, 1 # Decrement counter cmpwi r4, 0 bne process_loop # Continue if more halfwords
Unicode String Processing
# Process Unicode string using auto-increment lis r3, unicode_string@ha addi r3, r3, unicode_string@l subi r3, r3, 2 # Pre-adjust for first lhzu scan_unicode: lhzu r4, 2(r3) # Load next Unicode character and advance cmpwi r4, 0 # Check for null terminator beq end_of_string # Branch if end found # Check for specific Unicode ranges cmpwi r4, 0x0020 # Check for space beq found_space cmpwi r4, 0x00C0 # Check for accented characters bge accented_char # Regular ASCII character bl process_ascii b scan_unicode found_space: # Handle space character bl handle_space b scan_unicode accented_char: # Handle extended Unicode character bl handle_unicode b scan_unicode end_of_string: # r3 points to null terminator
Audio Sample Stream Processing
# Process 16-bit audio samples with automatic advance lis r3, audio_stream@ha addi r3, r3, audio_stream@l lwz r4, stream_length(r0) # Number of samples subi r3, r3, 2 # Pre-adjust pointer audio_process_loop: lhzu r5, 2(r3) # Load 16-bit sample and advance # Convert to signed if needed cmpwi r5, 32768 # Check if >= 32768 blt sample_positive subi r5, r5, 65536 # Convert to signed 16-bit sample_positive: # Apply audio processing (e.g., gain, filtering) lwz r6, gain_factor(r0) # Load gain (in fixed point) mullw r7, r5, r6 # Apply gain srwi r7, r7, 8 # Scale back (assuming 8.8 fixed point) # Clamp to valid range cmpwi r7, 32767 ble check_min li r7, 32767 # Clamp to maximum b store_sample check_min: cmpwi r7, -32768 bge store_sample li r7, -32768 # Clamp to minimum store_sample: # Convert back to unsigned for storage cmpwi r7, 0 bge sample_unsigned addi r7, r7, 65536 # Convert to unsigned sample_unsigned: sth r7, 0(r3) # Store processed sample subi r4, r4, 1 # Decrement sample count cmpwi r4, 0 bne audio_process_loop # Continue processing
Network Packet Header Parsing
# Parse network headers with 16-bit fields using update lis r3, packet_data@ha addi r3, r3, packet_data@l subi r3, r3, 2 # Pre-adjust for first lhzu parse_headers: # Ethernet header (simplified) addi r3, r3, 12 # Skip MAC addresses (6+6 bytes) lhzu r4, 2(r3) # Load EtherType and advance # Check EtherType cmpwi r4, 0x0800 # IPv4 beq parse_ipv4 cmpwi r4, 0x86DD # IPv6 beq parse_ipv6 cmpwi r4, 0x0806 # ARP beq parse_arp b unknown_protocol parse_ipv4: # IP header fields lhzu r5, 2(r3) # Load version/IHL + TOS lhzu r6, 2(r3) # Load total length lhzu r7, 2(r3) # Load identification lhzu r8, 2(r3) # Load flags + fragment offset lhzu r9, 2(r3) # Load TTL + protocol lhzu r10, 2(r3) # Load header checksum # Extract protocol field rlwinm r11, r9, 0, 24, 31 # Extract protocol (lower 8 bits) cmpwi r11, 6 # TCP beq parse_tcp cmpwi r11, 17 # UDP beq parse_udp cmpwi r11, 1 # ICMP beq parse_icmp b ip_payload_done parse_tcp: # Skip source and dest IP (8 bytes) addi r3, r3, 8 # TCP header lhzu r12, 2(r3) # Load source port lhzu r13, 2(r3) # Load destination port # Continue with TCP processing... b packet_done parse_udp: # Skip source and dest IP (8 bytes) addi r3, r3, 8 # UDP header lhzu r12, 2(r3) # Load source port lhzu r13, 2(r3) # Load destination port lhzu r14, 2(r3) # Load length lhzu r15, 2(r3) # Load checksum b packet_done parse_ipv6: parse_arp: unknown_protocol: ip_payload_done: packet_done:
Image Processing - Pixel Data
# Process 16-bit pixel data (RGB565 format) lis r3, image_data@ha addi r3, r3, image_data@l lwz r4, pixel_count(r0) # Total number of pixels subi r3, r3, 2 # Pre-adjust pointer pixel_loop: lhzu r5, 2(r3) # Load RGB565 pixel and advance # Extract color components # RGB565: RRRRRGGGGGGBBBBB rlwinm r6, r5, 27, 27, 31 # Extract red (bits 11-15) rlwinm r7, r5, 21, 26, 31 # Extract green (bits 5-10) rlwinm r8, r5, 16, 27, 31 # Extract blue (bits 0-4) # Scale to 8-bit values slwi r6, r6, 3 # Red: 5-bit to 8-bit slwi r7, r7, 2 # Green: 6-bit to 8-bit slwi r8, r8, 3 # Blue: 5-bit to 8-bit # Apply image filter (example: brightness adjustment) lwz r9, brightness_offset(r0) add r6, r6, r9 # Adjust red add r7, r7, r9 # Adjust green add r8, r8, r9 # Adjust blue # Clamp values to [0, 255] cmpwi r6, 255 ble red_ok li r6, 255 red_ok: cmpwi r6, 0 bge red_clamped li r6, 0 red_clamped: cmpwi r7, 255 ble green_ok li r7, 255 green_ok: cmpwi r7, 0 bge green_clamped li r7, 0 green_clamped: cmpwi r8, 255 ble blue_ok li r8, 255 blue_ok: cmpwi r8, 0 bge blue_clamped li r8, 0 blue_clamped: # Convert back to RGB565 srwi r6, r6, 3 # Scale red back to 5-bit srwi r7, r7, 2 # Scale green back to 6-bit srwi r8, r8, 3 # Scale blue back to 5-bit # Pack into RGB565 format slwi r10, r6, 11 # Red to bits 11-15 slwi r11, r7, 5 # Green to bits 5-10 or r12, r10, r11 # Combine red and green or r12, r12, r8 # Add blue # Store processed pixel sth r12, 0(r3) # Store back to image subi r4, r4, 1 # Decrement pixel count cmpwi r4, 0 bne pixel_loop # Continue processing
File Format Parsing
# Parse binary file with 16-bit length fields lis r3, file_data@ha addi r3, r3, file_data@l subi r3, r3, 2 # Pre-adjust for first read parse_file: # Read record type lhzu r4, 2(r3) # Load record type and advance cmpwi r4, 0 # Check for end marker beq file_done # Read record length lhzu r5, 2(r3) # Load length field and advance # Process based on record type cmpwi r4, 0x0001 # Header record beq process_header cmpwi r4, 0x0002 # Data record beq process_data cmpwi r4, 0x0003 # Index record beq process_index b skip_record # Unknown type process_header: # Process header data (r5 = length) mr r6, r3 # Save current position add r3, r3, r5 # Skip over header data bl handle_header # Process with r6=data, r5=length b parse_file process_data: # Process data payload mr r6, r3 # Save data start add r3, r3, r5 # Skip over data bl handle_data # Process with r6=data, r5=length b parse_file process_index: # Process index entries (each entry is 4 bytes) srwi r7, r5, 2 # Number of entries (length / 4) li r8, 0 # Entry counter index_loop: cmpw r8, r7 # Check if done beq index_done lwzu r9, 4(r3) # Load index entry (32-bit) and advance bl process_index_entry # Process entry addi r8, r8, 1 # Next entry b index_loop index_done: b parse_file skip_record: # Skip unknown record type add r3, r3, r5 # Skip over data b parse_file file_done:
Compression Stream Processing
# Decompress data stream with 16-bit length prefixes lis r3, compressed_data@ha addi r3, r3, compressed_data@l lis r4, output_buffer@ha addi r4, r4, output_buffer@l subi r3, r3, 2 # Pre-adjust input pointer decompress_stream: lhzu r5, 2(r3) # Load command word and advance # Check command type (bit 15) andi. r6, r5, 0x8000 bne copy_command # Branch if copy command # Literal run: lower 15 bits = length andi r7, r5, 0x7FFF # Extract length cmpwi r7, 0 # Check for end marker beq decompress_done literal_loop: lbzu r8, 1(r3) # Load literal byte and advance stbu r8, 1(r4) # Store to output and advance subi r7, r7, 1 # Decrement count cmpwi r7, 0 bne literal_loop # Continue literal run b decompress_stream copy_command: # Copy command: extract distance and length andi r7, r5, 0x0FFF # Extract distance (bits 0-11) rlwinm r8, r5, 20, 28, 31 # Extract length (bits 12-15) addi r8, r8, 3 # Minimum copy length is 3 # Calculate source address for copy sub r9, r4, r7 # output_ptr - distance copy_loop: lbz r10, 1(r9) # Load byte from copy source stbu r10, 1(r4) # Store to output and advance addi r9, r9, 1 # Advance source subi r8, r8, 1 # Decrement length cmpwi r8, 0 bne copy_loop # Continue copy b decompress_stream # Process next command decompress_done:
Game Asset Loading
# Load game assets with 16-bit headers lis r3, asset_data@ha addi r3, r3, asset_data@l subi r3, r3, 2 # Pre-adjust pointer load_assets: lhzu r4, 2(r3) # Load asset type and advance cmpwi r4, 0 # Check for end of assets beq assets_loaded lhzu r5, 2(r3) # Load asset size and advance # Process based on asset type cmpwi r4, ASSET_TEXTURE beq load_texture cmpwi r4, ASSET_SOUND beq load_sound cmpwi r4, ASSET_MODEL beq load_model cmpwi r4, ASSET_SCRIPT beq load_script b skip_asset # Unknown type load_texture: # Load texture data (r5 = size in bytes) mr r6, r3 # Save texture data pointer add r3, r3, r5 # Skip over texture data bl register_texture # Register with graphics system b load_assets load_sound: # Load sound data mr r6, r3 # Save sound data pointer add r3, r3, r5 # Skip over sound data bl register_sound # Register with audio system b load_assets load_model: # Load 3D model data mr r6, r3 # Save model data pointer add r3, r3, r5 # Skip over model data bl register_model # Register with 3D engine b load_assets load_script: # Load script/animation data mr r6, r3 # Save script data pointer add r3, r3, r5 # Skip over script data bl register_script # Register with script engine b load_assets skip_asset: # Skip unknown asset type add r3, r3, r5 # Skip over data b load_assets assets_loaded:
Database Record Processing
# Process database records with 16-bit field headers lis r3, db_records@ha addi r3, r3, db_records@l subi r3, r3, 2 # Pre-adjust pointer process_records: lhzu r4, 2(r3) # Load record type and advance cmpwi r4, 0xFFFF # Check for end marker beq records_done lhzu r5, 2(r3) # Load record size and advance # Validate record cmpwi r5, MAX_RECORD_SIZE bgt invalid_record cmpwi r5, MIN_RECORD_SIZE blt invalid_record # Process record fields mr r6, r3 # Save record start mr r7, r5 # Save record size li r8, 0 # Field offset field_loop: cmpw r8, r7 # Check if end of record bge record_complete add r9, r6, r8 # Calculate field address lhz r10, 0(r9) # Load field type lhz r11, 2(r9) # Load field length # Process field based on type cmpwi r10, FIELD_STRING beq process_string_field cmpwi r10, FIELD_INTEGER beq process_int_field cmpwi r10, FIELD_TIMESTAMP beq process_time_field b skip_field process_string_field: # Process string field (r9=field addr, r11=length) addi r12, r9, 4 # Skip type and length bl process_string # Process string data b next_field process_int_field: # Process integer field lwz r12, 4(r9) # Load integer value bl process_integer # Process integer b next_field process_time_field: # Process timestamp field lwz r12, 4(r9) # Load timestamp (high) lwz r13, 8(r9) # Load timestamp (low) bl process_timestamp # Process timestamp b next_field skip_field: next_field: addi r8, r8, 4 # Move past type and length add r8, r8, r11 # Skip field data b field_loop record_complete: add r3, r3, r5 # Skip to next record b process_records invalid_record: # Handle invalid record add r3, r3, r5 # Skip bad record bl log_error # Log the error b process_records records_done: