Instruction Syntax
Mnemonic | Format | Flags |
lwa | rD,d(rA) | - |
Instruction Encoding
Field | Bits | Description |
Primary Opcode | 0-5 | 111000 (0x38) |
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 ← EXTS(MEM(EA, 4))
A word (32 bits) is loaded from memory, sign-extended to 64 bits, and placed in register rD. The effective address is computed by adding the sign-extended displacement to the contents of register rA, or zero if rA is 0.
Note: This instruction is part of the 64-bit PowerPC architecture extensions. Unlike lwz
which zero-extends, this instruction sign-extends the loaded word to 64 bits, preserving the sign for signed 32-bit values. This is essential for processing signed integer data in 64-bit environments. 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
64-bit Integer Processing
# Process 32-bit signed integers in 64-bit environment lis r3, signed_data@ha addi r3, r3, signed_data@l lwz r4, num_elements(r0) # Number of elements # Load and process signed 32-bit values processing_loop: lwa r5, 0(r3) # Load signed 32-bit value (sign-extended to 64-bit) # Perform 64-bit arithmetic operations # The value is already properly sign-extended for 64-bit operations addi r6, r5, 1000 # Add constant (64-bit addition) mullw r7, r5, r5 # Square the value (64-bit multiplication) # Store result back stw r7, 0(r3) # Store 32-bit result addi r3, r3, 4 # Next element subi r4, r4, 1 # Decrement counter cmpwi r4, 0 bne processing_loop # Continue processing
Large Number Arithmetic
# Handle large signed numbers that require 64-bit precision lis r3, large_numbers@ha addi r3, r3, large_numbers@l lwz r4, array_size(r0) # Array size # Process large signed integers large_number_loop: lwa r5, 0(r3) # Load signed 32-bit value (sign-extended) # Perform calculations that might overflow 32-bit arithmetic # Since the value is sign-extended to 64 bits, we can safely # perform large calculations without overflow # Example: Calculate factorial-like operation li r6, 1 # Initialize result li r7, 1 # Counter factorial_loop: cmpw r7, r5 # Compare counter with input value bgt factorial_done # Exit if counter > input mullw r6, r6, r7 # result *= counter addi r7, r7, 1 # Increment counter b factorial_loop # Continue factorial calculation factorial_done: # Store result (truncate to 32 bits if necessary) stw r6, 0(r3) # Store result addi r3, r3, 4 # Next element subi r4, r4, 1 # Decrement counter cmpwi r4, 0 bne large_number_loop # Continue processing
64-bit Address Calculations
# Work with 64-bit addresses and offsets lis r3, address_array@ha addi r3, r3, address_array@l lwz r4, num_addresses(r0) # Number of addresses # Process 64-bit address calculations address_processing_loop: lwa r5, 0(r3) # Load signed 32-bit offset (sign-extended to 64-bit) # Add offset to base address lis r6, base_address@ha addi r6, r6, base_address@l add r7, r6, r5 # base_address + offset (64-bit addition) # Validate address range lis r8, memory_start@ha addi r8, r8, memory_start@l lis r9, memory_end@ha addi r9, r9, memory_end@l cmpw r7, r8 # Check lower bound blt invalid_address # Branch if below memory start cmpw r7, r9 # Check upper bound bgt invalid_address # Branch if above memory end # Valid address - perform operation bl process_valid_address b next_address invalid_address: bl handle_invalid_address next_address: addi r3, r3, 4 # Next address offset subi r4, r4, 1 # Decrement counter cmpwi r4, 0 bne address_processing_loop # Continue processing
Time Stamp Processing
# Process 32-bit signed timestamps in 64-bit environment lis r3, timestamp_data@ha addi r3, r3, timestamp_data@l lwz r4, num_timestamps(r0) # Number of timestamps # Process timestamps with 64-bit arithmetic timestamp_loop: lwa r5, 0(r3) # Load signed timestamp (sign-extended to 64-bit) # Calculate time differences (can be negative) lwz r6, reference_time(r0) # Load reference time sub r7, r5, r6 # time_delta = timestamp - reference (64-bit subtraction) # Convert to different time units # Convert seconds to milliseconds li r8, 1000 # 1000 milliseconds per second mullw r9, r7, r8 # milliseconds = seconds * 1000 # Convert to microseconds li r10, 1000000 # 1,000,000 microseconds per second mullw r11, r7, r10 # microseconds = seconds * 1000000 # Store converted values stw r9, 0(r3) # Store milliseconds stw r11, 4(r3) # Store microseconds addi r3, r3, 8 # Next timestamp (8 bytes for two values) subi r4, r4, 1 # Decrement counter cmpwi r4, 0 bne timestamp_loop # Continue processing
Financial Calculations
# Perform financial calculations with large signed numbers lis r3, financial_data@ha addi r3, r3, financial_data@l lwz r4, num_transactions(r0) # Number of financial transactions # Process financial transactions financial_loop: lwa r5, 0(r3) # Load signed transaction amount (sign-extended) # Calculate compound interest # Formula: A = P(1 + r/n)^(nt) # Where: P = principal, r = rate, n = compounds per year, t = time lwz r6, principal(r0) # Load principal amount lwz r7, interest_rate(r0) # Load interest rate (percentage) lwz r8, compounds_per_year(r0) # Load compounds per year lwz r9, years(r0) # Load time in years # Convert percentage to decimal li r10, 100 # 100 for percentage conversion divw r11, r7, r10 # rate_decimal = rate / 100 # Calculate (1 + r/n) divw r12, r11, r8 # r/n addi r13, r12, 1 # 1 + r/n # Calculate (1 + r/n)^(nt) mullw r14, r8, r9 # nt # Note: This is a simplified calculation # In practice, you'd use a more sophisticated power function # Calculate final amount mullw r15, r6, r13 # P * (1 + r/n) # Store result stw r15, 0(r3) # Store calculated amount addi r3, r3, 4 # Next transaction subi r4, r4, 1 # Decrement counter cmpwi r4, 0 bne financial_loop # Continue processing
Scientific Computing - Large Integer Operations
# Perform scientific calculations with large signed integers lis r3, scientific_data@ha addi r3, r3, scientific_data@l lwz r4, data_size(r0) # Size of scientific data # Process scientific data with 64-bit precision scientific_loop: lwa r5, 0(r3) # Load signed scientific value (sign-extended) # Perform mathematical operations that require 64-bit precision # Example: Calculate large powers # Calculate 2^n where n is the input value li r6, 1 # Initialize result li r7, 0 # Counter power_loop: cmpw r7, r5 # Compare counter with exponent bge power_done # Exit if counter >= exponent slwi r6, r6, 1 # result *= 2 (left shift) addi r7, r7, 1 # Increment counter b power_loop # Continue power calculation power_done: # Calculate factorial of the result li r8, 1 # Initialize factorial result li r9, 1 # Factorial counter factorial_calc: cmpw r9, r6 # Compare counter with input bgt factorial_calc_done # Exit if counter > input mullw r8, r8, r9 # factorial_result *= counter addi r9, r9, 1 # Increment counter b factorial_calc # Continue factorial calculation factorial_calc_done: # Store results stw r6, 0(r3) # Store power result stw r8, 4(r3) # Store factorial result addi r3, r3, 8 # Next data element (8 bytes for two results) subi r4, r4, 1 # Decrement counter cmpwi r4, 0 bne scientific_loop # Continue processing
Database Operations - Large Record Processing
# Process large database records with 64-bit addressing lis r3, database_records@ha addi r3, r3, database_records@l lwz r4, num_records(r0) # Number of database records # Process database records database_loop: lwa r5, 0(r3) # Load signed record ID (sign-extended to 64-bit) # Calculate record offset in database li r6, RECORD_SIZE # Size of each record mullw r7, r5, r6 # record_offset = record_id * record_size # Add base address to get actual record location lis r8, database_base@ha addi r8, r8, database_base@l add r9, r8, r7 # record_address = base + offset # Validate record address lis r10, database_start@ha addi r10, r10, database_start@l lis r11, database_end@ha addi r11, r11, database_end@l cmpw r9, r10 # Check lower bound blt invalid_record # Branch if below database start cmpw r9, r11 # Check upper bound bgt invalid_record # Branch if above database end # Valid record - process it bl process_database_record b next_record invalid_record: bl handle_invalid_record next_record: addi r3, r3, 4 # Next record ID subi r4, r4, 1 # Decrement counter cmpwi r4, 0 bne database_loop # Continue processing