lhax
Load Halfword Algebraic Indexed - 7C 00 02 AE
lhax

Instruction Syntax

Mnemonic Format Flags
lhax rD,rA,rB -

Instruction Encoding

0
1
1
1
1
1
D
D
D
D
D
A
A
A
A
A
B
B
B
B
B
0
1
0
1
0
1
0
1
1
1
/

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

Related Instructions

lha, lhau, lhaux, sthx, lhzx, lwzx

Back to Index