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: