lhzu
Load Halfword and Zero with Update - A4 00 00 00
lhzu

Instruction Syntax

Mnemonic Format Flags
lhzu rD,d(rA) -

Instruction Encoding

1
0
1
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 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:

Related Instructions

lhz, lhzx, lhzux, sthu, lbzu, lwzu

Back to Index