lhz
Load Halfword and Zero - A0 00 00 00
lhz
Instruction Syntax
Mnemonic | Format | Flags |
lhz | rD,d(rA) | - |
Instruction Encoding
1
0
1
0
0
0
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 | 101000 (0x28) |
rD | 6-10 | Destination register |
rA | 11-15 | Source register A |
d | 16-31 | 16-bit signed displacement |
Operation
if rA = 0 then EA ← EXTS(d) else EA ← (rA) + EXTS(d) rD ← 0x0000 || MEM(EA, 2)
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, or zero if rA is 0.
Note: The effective address should be halfword-aligned (divisible by 2) for optimal performance. If rA=0, it is treated as the value 0, not the contents of register r0.
Affected Registers
None - This instruction does not affect any condition register fields or XER register bits.
For more information on memory addressing see Section 2.1.6, "Effective Address Calculation," in the PowerPC Microprocessor Family: The Programming Environments manual.
Examples
Basic Halfword Loading
lhz r3, 0(r1) # Load halfword from address in r1 lhz r4, 100(r2) # Load halfword from address r2+100 lhz r5, -50(r3) # Load halfword from address r3-50
Unicode Character Loading
# Load Unicode characters (16-bit) lis r3, unicode_string@ha addi r3, r3, unicode_string@l li r4, 5 # Character index slwi r5, r4, 1 # Multiply by 2 (sizeof(wchar_t)) lhzx r6, r3, r5 # Load unicode_string[5] # Or using displacement: lhz r7, 10(r3) # Load character at offset 10 (index 5)
Network Protocol Header Parsing
# Parse network packet header with 16-bit fields lis r3, packet_buffer@ha addi r3, r3, packet_buffer@l lhz r4, 0(r3) # Load packet type (16-bit) lhz r5, 2(r3) # Load packet length (16-bit) lhz r6, 4(r3) # Load source port (16-bit) lhz r7, 6(r3) # Load destination port (16-bit) lhz r8, 8(r3) # Load checksum (16-bit) # Validate packet length cmpwi r5, 1500 # Check against maximum MTU bgt invalid_packet # Branch if too large
Audio Sample Loading (16-bit)
# Load 16-bit audio samples lis r3, audio_buffer@ha addi r3, r3, audio_buffer@l lwz r4, sample_count(r0) # Number of samples li r5, 0 # Sample index load_samples: slwi r6, r5, 1 # Convert index to byte offset lhzx r7, r3, r6 # Load 16-bit sample # Convert unsigned to signed if needed cmpwi r7, 32768 # Check if >= 32768 blt positive_sample subi r7, r7, 65536 # Convert to signed 16-bit positive_sample: # Process sample in r7 bl process_audio_sample addi r5, r5, 1 # Next sample cmpw r5, r4 # Check if done blt load_samples # Continue if more samples
Image Pixel Data (16-bit RGB565)
# Load 16-bit RGB565 pixel data lis r3, image_data@ha addi r3, r3, image_data@l lwz r4, image_width(r0) lwz r5, image_height(r0) li r6, 0 # Y coordinate li r7, 0 # X coordinate load_pixels: mullw r8, r6, r4 # Calculate row offset add r8, r8, r7 # Add column offset slwi r8, r8, 1 # Convert to byte offset lhzx r9, r3, r8 # Load RGB565 pixel # Extract color components rlwinm r10, r9, 0, 27, 31 # Extract blue (bits 0-4) rlwinm r11, r9, 21, 26, 31 # Extract green (bits 5-10) rlwinm r12, r9, 16, 27, 31 # Extract red (bits 11-15) # Process pixel components bl process_pixel # Pass r10=blue, r11=green, r12=red # Advance to next pixel addi r7, r7, 1 # Next column cmpw r7, r4 # Check end of row blt load_pixels # Continue row li r7, 0 # Reset column addi r6, r6, 1 # Next row cmpw r6, r5 # Check end of image blt load_pixels # Continue image
File System Directory Entry
# Parse FAT directory entry (16-bit fields) lis r3, dir_entry@ha addi r3, r3, dir_entry@l # FAT directory entry structure (simplified) lhz r4, 0(r3) # Load first cluster (low 16 bits) lhz r5, 20(r3) # Load first cluster (high 16 bits) lhz r6, 22(r3) # Load creation time lhz r7, 24(r3) # Load creation date lhz r8, 26(r3) # Load last access date lhz r9, 28(r3) # Load last write time lhz r10, 30(r3) # Load last write date # Combine high and low cluster numbers slwi r5, r5, 16 # Shift high part to upper 16 bits or r11, r4, r5 # Combine into full 32-bit cluster number
Graphics Texture Coordinate Loading
# Load texture coordinates (16-bit fixed point) lis r3, texture_coords@ha addi r3, r3, texture_coords@l li r4, 10 # Vertex index slwi r5, r4, 2 # 4 bytes per vertex (2 coordinates) add r6, r3, r5 # Vertex coordinate address lhz r7, 0(r6) # Load U coordinate (16-bit) lhz r8, 2(r6) # Load V coordinate (16-bit) # Convert from fixed point to floating point # Assuming format is 8.8 fixed point li r9, 256 # Scale factor stw r7, temp_u(r1) # Store to memory stw r8, temp_v(r1) lfs f1, temp_u(r1) # Load as float lfs f2, temp_v(r1) li r10, 256 stw r10, scale(r1) lfs f3, scale(r1) fdivs f1, f1, f3 # Convert to float fdivs f2, f2, f3
Configuration Data Loading
# Load device configuration values (16-bit) lis r3, config_block@ha addi r3, r3, config_block@l lhz r4, CFG_DEVICE_ID(r3) # Load device ID lhz r5, CFG_REVISION(r3) # Load revision number lhz r6, CFG_CAPABILITIES(r3) # Load capability flags lhz r7, CFG_MAX_SPEED(r3) # Load maximum speed lhz r8, CFG_BUFFER_SIZE(r3) # Load buffer size # Validate configuration lis r9, EXPECTED_DEVICE_ID@ha ori r9, r9, EXPECTED_DEVICE_ID@l cmpw r4, r9 # Check device ID bne wrong_device # Branch if mismatch cmpwi r5, MIN_REVISION # Check minimum revision blt unsupported_revision # Branch if too old
Compression Dictionary Loading
# Load compression dictionary entries (16-bit indices) lis r3, compression_dict@ha addi r3, r3, compression_dict@l lis r4, input_stream@ha addi r4, r4, input_stream@l decompress_loop: lhz r5, 0(r4) # Load dictionary index (16-bit) cmpwi r5, 0 # Check for end marker beq decompress_done # Look up dictionary entry slwi r6, r5, 1 # Convert to byte offset lhzx r7, r3, r6 # Load dictionary value # Output decompressed value stb r7, output_buffer(r8) addi r8, r8, 1 # Advance output pointer addi r4, r4, 2 # Advance input pointer b decompress_loop decompress_done:
MIDI Note Data
# Load MIDI note information (16-bit values) lis r3, midi_sequence@ha addi r3, r3, midi_sequence@l li r4, 0 # Time offset play_sequence: lhz r5, 0(r3) # Load delta time (16-bit) lhz r6, 2(r3) # Load note data (pitch + velocity) add r4, r4, r5 # Update current time # Extract note information rlwinm r7, r6, 0, 24, 31 # Extract note number (bits 0-7) rlwinm r8, r6, 24, 24, 31 # Extract velocity (bits 8-15) cmpwi r8, 0 # Check for note off beq note_off # Note on bl play_note # Pass r7=note, r8=velocity, r4=time b next_event note_off: bl stop_note # Pass r7=note, r4=time next_event: addi r3, r3, 4 # Move to next event lhz r9, 0(r3) # Check for end marker cmpwi r9, 0xFFFF bne play_sequence # Continue if not end
Database Record Field Access
# Access 16-bit fields in database record lis r3, record_buffer@ha addi r3, r3, record_buffer@l lhz r4, FIELD_ID(r3) # Load record ID (16-bit) lhz r5, FIELD_TYPE(r3) # Load record type (16-bit) lhz r6, FIELD_FLAGS(r3) # Load flags (16-bit) lhz r7, FIELD_SIZE(r3) # Load data size (16-bit) lhz r8, FIELD_CHECKSUM(r3) # Load checksum (16-bit) # Validate record cmpwi r4, 0 # Check for valid ID beq invalid_record cmpwi r7, MAX_RECORD_SIZE # Check size limit bgt record_too_large # Check record type cmpwi r5, TYPE_USER_DATA beq process_user_data cmpwi r5, TYPE_SYSTEM_DATA beq process_system_data b unknown_record_type
Network Port Scanning
# Scan network services on different ports lis r3, port_list@ha addi r3, r3, port_list@l lwz r4, port_count(r0) # Number of ports to scan li r5, 0 # Port index scan_ports: slwi r6, r5, 1 # Convert to byte offset lhzx r7, r3, r6 # Load port number (16-bit) # Attempt connection to port mr r3, r7 # Pass port number bl attempt_connection cmpwi r3, 0 # Check connection result beq connection_failed # Port is open mr r3, r7 # Pass port number bl identify_service # Identify service on port connection_failed: addi r5, r5, 1 # Next port cmpw r5, r4 # Check if done blt scan_ports # Continue scanning