Instruction Syntax
Mnemonic | Format | Flags |
lhax | rD,rA,rB | - |
Instruction Encoding
Field | Bits | Description |
Primary Opcode | 0-5 | 011111 (0x1F) |
rD | 6-10 | Destination register |
rA | 11-15 | Source register A |
rB | 16-20 | Source register B |
XO | 21-30 | 343 (Extended opcode) |
Rc | 31 | Reserved (0) |
Operation
if rA = 0 then EA ← (rB) else EA ← (rA) + (rB) rD ← EXTS(MEM(EA, 2))
A halfword (16 bits) is loaded from memory, sign-extended to 32 bits, and placed in register rD. The effective address is computed by adding the contents of registers rA and rB, or just rB if rA is 0.
Note: This indexed form is essential for array access and dynamic addressing with signed 16-bit data. The sign extension preserves the sign of signed halfword values, making it ideal for processing signed integer arrays, sensor data, and audio samples. If rA=0, it is treated as the value 0, not the contents of register r0.
Affected Registers
None (load instruction does not affect condition registers).
For more information on memory addressing see Section 2.1.6, "Effective Address Calculation," in the PowerPC Microprocessor Family: The Programming Environments manual.
Examples
Matrix Operations with Signed Elements
# Access signed matrix elements using computed indices lis r3, signed_matrix@ha addi r3, r3, signed_matrix@l lwz r4, matrix_rows(r0) # Number of rows lwz r5, matrix_cols(r0) # Number of columns # Matrix element access: matrix[row][col] li r6, 2 # Row index li r7, 3 # Column index # Calculate element address: base + (row * cols + col) * 2 mullw r8, r6, r5 # row * cols add r9, r8, r7 # + col slwi r10, r9, 1 # * 2 (bytes per signed halfword) lhax r11, r3, r10 # Load signed matrix[row][col] # Process matrix element (already sign-extended) bl process_matrix_element # Process signed value in r11
Digital Signal Processing - Filter Coefficient Access
# Access filter coefficients with dynamic indexing lis r3, filter_bank@ha addi r3, r3, filter_bank@l lis r4, coefficient_indices@ha addi r4, r4, coefficient_indices@l lwz r5, num_filters(r0) # Number of filters in bank filter_processing_loop: # Load coefficient index for current filter lwz r6, 0(r4) # Load coefficient index slwi r7, r6, 1 # Convert to byte offset lhax r8, r3, r7 # Load signed filter coefficient # Apply coefficient to signal processing lwz r9, current_sample(r0) # Load current signal sample mullw r10, r8, r9 # coefficient * sample srawi r11, r10, 8 # Scale result (8-bit fractional) # Store processed result stw r11, processed_sample(r0) addi r4, r4, 4 # Next coefficient index subi r5, r5, 1 # Decrement filter counter cmpwi r5, 0 bne filter_processing_loop # Continue processing
Game AI - Pathfinding Grid
# Navigate AI pathfinding grid with signed cost values lis r3, pathfinding_grid@ha addi r3, r3, pathfinding_grid@l lwz r4, grid_width(r0) # Grid width lwz r5, start_x(r0) # Starting X position lwz r6, start_y(r0) # Starting Y position lwz r7, target_x(r0) # Target X position lwz r8, target_y(r0) # Target Y position # A* pathfinding algorithm with signed movement costs pathfinding_loop: # Calculate current grid position mullw r9, r6, r4 # current_y * grid_width add r10, r9, r5 # + current_x slwi r11, r10, 1 # Convert to byte offset lhax r12, r3, r11 # Load movement cost (signed) # Check for obstacles (negative costs indicate walls) cmpwi r12, 0 # Check if passable blt obstacle_found # Branch if obstacle # Calculate movement in each direction # North: y - 1 subi r13, r6, 1 # y - 1 cmpwi r13, 0 # Check bounds blt check_south # Skip if out of bounds mullw r14, r13, r4 # (y-1) * width add r15, r14, r5 # + x slwi r16, r15, 1 # Convert to byte offset lhax r17, r3, r16 # Load north cell cost cmpwi r17, 0 # Check if passable bge calculate_north_cost # Calculate cost if passable check_south: # South: y + 1 addi r18, r6, 1 # y + 1 lwz r19, grid_height(r0) # Load grid height cmpw r18, r19 # Check bounds bge check_east # Skip if out of bounds mullw r20, r18, r4 # (y+1) * width add r21, r20, r5 # + x slwi r22, r21, 1 # Convert to byte offset lhax r23, r3, r22 # Load south cell cost cmpwi r23, 0 # Check if passable bge calculate_south_cost # Calculate cost if passable check_east: # East: x + 1 addi r24, r5, 1 # x + 1 cmpw r24, r4 # Check bounds (x < width) bge check_west # Skip if out of bounds mullw r25, r6, r4 # y * width add r26, r25, r24 # + (x+1) slwi r27, r26, 1 # Convert to byte offset lhax r28, r3, r27 # Load east cell cost cmpwi r28, 0 # Check if passable bge calculate_east_cost # Calculate cost if passable check_west: # West: x - 1 subi r29, r5, 1 # x - 1 cmpwi r29, 0 # Check bounds blt pathfinding_complete # Skip if out of bounds mullw r30, r6, r4 # y * width add r31, r30, r29 # + (x-1) slwi r0, r31, 1 # Convert to byte offset lhax r1, r3, r0 # Load west cell cost cmpwi r1, 0 # Check if passable bge calculate_west_cost # Calculate cost if passable b pathfinding_complete calculate_north_cost: # Calculate heuristic cost to target sub r2, r7, r5 # target_x - current_x sub r3, r8, r13 # target_y - (current_y - 1) abs r4, r2 # |delta_x| abs r5, r3 # |delta_y| add r6, r4, r5 # Manhattan distance add r7, r17, r6 # movement_cost + heuristic bl add_to_open_list # Add to pathfinding open list b check_south calculate_south_cost: # Similar calculations for south direction sub r8, r7, r5 # target_x - current_x sub r9, r8, r18 # target_y - (current_y + 1) abs r10, r8 # |delta_x| abs r11, r9 # |delta_y| add r12, r10, r11 # Manhattan distance add r13, r23, r12 # movement_cost + heuristic bl add_to_open_list # Add to pathfinding open list b check_east calculate_east_cost: # Similar calculations for east direction sub r14, r7, r24 # target_x - (current_x + 1) sub r15, r8, r6 # target_y - current_y abs r16, r14 # |delta_x| abs r17, r15 # |delta_y| add r18, r16, r17 # Manhattan distance add r19, r28, r18 # movement_cost + heuristic bl add_to_open_list # Add to pathfinding open list b check_west calculate_west_cost: # Similar calculations for west direction sub r20, r7, r29 # target_x - (current_x - 1) sub r21, r8, r6 # target_y - current_y abs r22, r20 # |delta_x| abs r23, r21 # |delta_y| add r24, r22, r23 # Manhattan distance add r25, r1, r24 # movement_cost + heuristic bl add_to_open_list # Add to pathfinding open list b pathfinding_complete obstacle_found: bl handle_obstacle # Handle obstacle in pathfinding pathfinding_complete: bl get_next_open_node # Get next node from open list # Continue pathfinding until target reached
Image Processing - Histogram Equalization
# Perform histogram equalization on signed image data lis r3, signed_image@ha addi r3, r3, signed_image@l lis r4, histogram@ha addi r4, r4, histogram@l lwz r5, image_size(r0) # Total number of pixels # First pass: build histogram li r6, 0 # Pixel counter histogram_build_loop: slwi r7, r6, 1 # Convert pixel index to byte offset lhax r8, r3, r7 # Load signed pixel value # Normalize pixel value to histogram index (0-255) # For signed 16-bit: map [-32768, 32767] to [0, 255] addi r9, r8, 32768 # Shift to unsigned range [0, 65535] srwi r10, r9, 8 # Scale to [0, 255] # Increment histogram bin slwi r11, r10, 2 # Convert to word offset lwzx r12, r4, r11 # Load current histogram count addi r13, r12, 1 # Increment count stwx r13, r4, r11 # Store updated count addi r6, r6, 1 # Next pixel cmpw r6, r5 # Check if done with image blt histogram_build_loop # Continue histogram building # Second pass: calculate cumulative distribution function (CDF) li r14, 0 # Cumulative sum li r15, 0 # Histogram bin index cdf_calculation_loop: cmpwi r15, 256 # Check if done with all bins bge equalization_pass slwi r16, r15, 2 # Convert bin to word offset lwzx r17, r4, r16 # Load histogram count add r14, r14, r17 # Add to cumulative sum # Store CDF value (normalized to 0-255 range) mullw r18, r14, 255 # cumulative_sum * 255 divw r19, r18, r5 # / total_pixels lis r20, cdf_table@ha addi r20, r20, cdf_table@l slwi r21, r15, 1 # Convert to halfword offset sthx r19, r20, r21 # Store CDF value addi r15, r15, 1 # Next histogram bin b cdf_calculation_loop # Continue CDF calculation equalization_pass: # Third pass: apply histogram equalization li r22, 0 # Pixel counter equalization_loop: slwi r23, r22, 1 # Convert pixel index to byte offset lhax r24, r3, r23 # Load original signed pixel value # Map pixel through equalization table addi r25, r24, 32768 # Shift to unsigned range srwi r26, r25, 8 # Scale to [0, 255] for table lookup # Load equalized value from CDF table lis r27, cdf_table@ha addi r27, r27, cdf_table@l slwi r28, r26, 1 # Convert to halfword offset lhax r29, r27, r28 # Load equalized value # Convert back to signed range [-32768, 32767] slwi r30, r29, 8 # Scale back to 16-bit range subi r31, r30, 32768 # Shift back to signed range # Store equalized pixel sthx r31, r3, r23 # Store equalized pixel value addi r22, r22, 1 # Next pixel cmpw r22, r5 # Check if done with image blt equalization_loop # Continue equalization
Network Protocol - Packet Header Analysis
# Analyze network packet headers with signed field values lis r3, packet_buffer@ha addi r3, r3, packet_buffer@l lis r4, field_offsets@ha addi r4, r4, field_offsets@l lwz r5, num_packets(r0) # Number of packets to analyze packet_analysis_loop: # Analyze custom protocol with signed header fields # Field offsets vary based on protocol version # Load protocol version to determine field layout lwz r6, 0(r4) # Load version field offset lhax r7, r3, r6 # Load protocol version (signed) cmpwi r7, 0 # Check protocol version blt legacy_protocol # Handle legacy versions (negative) cmpwi r7, 10 # Check for newer versions bge advanced_protocol # Handle advanced features # Standard protocol processing lwz r8, 4(r4) # Load sequence number offset lhax r9, r3, r8 # Load signed sequence number # Handle sequence number wraparound lwz r10, expected_sequence(r0) sub r11, r9, r10 # Calculate sequence delta # Check for reasonable sequence progression cmpwi r11, -100 # Check for reasonable negative delta blt sequence_error # Handle sequence error cmpwi r11, 100 # Check for reasonable positive delta bgt sequence_error # Handle sequence error # Load and validate checksum field lwz r12, 8(r4) # Load checksum offset lhax r13, r3, r12 # Load signed checksum # Calculate expected checksum bl calculate_checksum # Calculate checksum for packet # Returns expected checksum in r14 cmpw r13, r14 # Compare checksums bne checksum_error # Handle checksum mismatch # Load priority field (can be negative for low priority) lwz r15, 12(r4) # Load priority offset lhax r16, r3, r15 # Load signed priority value # Process based on priority cmpwi r16, 0 # Check priority level blt low_priority # Handle low priority packets cmpwi r16, 100 # Check for high priority bge high_priority # Handle high priority packets # Normal priority processing bl process_normal_packet b next_packet legacy_protocol: # Handle legacy protocol versions (negative version numbers) bl process_legacy_packet b next_packet advanced_protocol: # Handle advanced protocol features bl process_advanced_packet b next_packet sequence_error: bl handle_sequence_error b next_packet checksum_error: bl handle_checksum_error b next_packet low_priority: bl queue_low_priority_packet b next_packet high_priority: bl process_high_priority_packet next_packet: addi r3, r3, PACKET_SIZE # Next packet buffer addi r4, r4, 16 # Next field offset set subi r5, r5, 1 # Decrement packet counter cmpwi r5, 0 bne packet_analysis_loop # Continue packet analysis