icbi
Instruction Cache Block Invalidate - 7C 00 07 AC
icbi
Instruction Syntax
| Mnemonic | Format | Flags |
| icbi | rA,rB | - |
Instruction Encoding
0
1
1
1
1
1
0
0
0
0
0
A
A
A
A
A
B
B
B
B
B
0
1
1
1
1
0
1
0
1
1
0
| Field | Bits | Description |
| Primary Opcode | 0-5 | 011111 (0x1F) |
| Reserved | 6-10 | 00000 |
| rA | 11-15 | Source register A |
| rB | 16-20 | Source register B |
| Reserved | 21 | 0 |
| XO | 22-30 | 1111010110 (982) |
| Reserved | 31 | 0 |
Operation
if rA = 0 then EA ← 0 else EA ← (rA) EA ← EA + (rB) Invalidate instruction cache block containing EA
The instruction cache block containing the effective address is invalidated. If rA is 0, the effective address is the contents of rB. Otherwise, the effective address is the sum of the contents of rA and rB.
Note: This instruction is essential for self-modifying code and dynamic code generation. After invalidating the instruction cache, an isync instruction should be executed to ensure coherency. The invalidation only affects the instruction cache, not the data cache.
Affected Registers
None - This instruction does not affect any registers.
For more information on cache management see Section 2.1.1, "Cache Model," in the PowerPC Microprocessor Family: The Programming Environments manual.
Examples
Basic Instruction Cache Invalidation
# Invalidate instruction cache for specific address lis r3, code_addr@ha addi r3, r3, code_addr@l icbi 0, r3 # Invalidate instruction cache block at r3 isync # Ensure instruction fetch coherency
Self-Modifying Code Pattern
# Typical pattern for self-modifying code lis r3, dynamic_code@ha addi r3, r3, dynamic_code@l # Modify the instruction in memory lis r4, new_instruction@ha addi r4, r4, new_instruction@l lwz r5, 0(r4) # Load new instruction stw r5, 0(r3) # Store new instruction to code area # Ensure cache coherency dcbst 0, r3 # Store data cache block sync # Ensure store completes icbi 0, r3 # Invalidate instruction cache block isync # Synchronize instruction fetch
Dynamic Code Generation
# Generate code at runtime and ensure cache coherency lis r3, code_buffer@ha addi r3, r3, code_buffer@l # Generate instruction sequence (simplified example) lis r4, 0x3860 # Start of "li r3, value" instruction ori r4, r4, 42 # Complete instruction: li r3, 42 stw r4, 0(r3) # Store generated instruction # Flush data cache and invalidate instruction cache dcbst 0, r3 # Ensure data reaches main memory sync # Wait for store to complete icbi 0, r3 # Invalidate instruction cache isync # Synchronize instruction prefetch # Now safe to execute generated code mtctr r3 # Move code address to count register bcctr 20, 0 # Execute generated code
JIT Compiler Cache Management
# JIT compiler code cache management
lis r3, jit_cache@ha
addi r3, r3, jit_cache@l
li r4, 0 # Start offset
li r5, 1024 # Cache size in bytes
li r6, 32 # Cache line size
jit_invalidate_loop:
add r7, r3, r4 # Calculate current address
dcbst 0, r7 # Flush data cache
icbi 0, r7 # Invalidate instruction cache
addi r4, r4, 32 # Move to next cache line
cmpw r4, r5 # Compare with total size
blt jit_invalidate_loop
sync # Ensure all stores complete
isync # Synchronize instruction fetch
Kernel Module Loading
# Kernel module cache invalidation
lis r3, module_base@ha
addi r3, r3, module_base@l
lwz r4, module_size(r0) # Load module size
li r5, 0 # Current offset
li r6, 32 # Cache line size
module_cache_flush:
add r7, r3, r5 # Current address
dcbst 0, r7 # Flush data cache line
icbi 0, r7 # Invalidate instruction cache line
add r5, r5, r6 # Next cache line
cmpw r5, r4 # Check if done
blt module_cache_flush
sync # Memory barrier
isync # Instruction synchronization
Code Patching for Debugging
# Patch instruction for debugging/tracing lis r3, patch_point@ha addi r3, r3, patch_point@l # Save original instruction lwz r4, 0(r3) stw r4, saved_instruction(r0) # Install debug trap lis r5, 0x7FE0 # Start of trap instruction ori r5, r5, 0x0008 # Complete: trap stw r5, 0(r3) # Install trap instruction # Ensure cache coherency dcbst 0, r3 # Flush modified instruction sync # Wait for store icbi 0, r3 # Invalidate instruction cache isync # Synchronize prefetch
Function Prologue/Epilogue Patching
# Patch function entry points for profiling
lis r3, function_list@ha
addi r3, r3, function_list@l
lwz r4, num_functions(r0)
li r5, 0
patch_functions_loop:
lwzx r6, r3, r5 # Load function address
# Save original first instruction
lwz r7, 0(r6)
stwx r7, r3, r5 # Save in parallel array
# Install profiling call
lis r8, profile_call@ha
addi r8, r8, profile_call@l
stw r8, 0(r6) # Patch function entry
# Invalidate cache for this function
dcbst 0, r6 # Flush data cache
icbi 0, r6 # Invalidate instruction cache
addi r5, r5, 4 # Next function
subi r4, r4, 1 # Decrement counter
cmpwi r4, 0
bne patch_functions_loop
sync # Ensure all modifications complete
isync # Synchronize instruction stream
Bootloader Code Relocation
# Relocate code and ensure cache coherency
lis r3, source_addr@ha
addi r3, r3, source_addr@l
lis r4, dest_addr@ha
addi r4, r4, dest_addr@l
lwz r5, copy_size(r0)
li r6, 0
relocate_loop:
lwzx r7, r3, r6 # Load from source
stwx r7, r4, r6 # Store to destination
# Maintain cache coherency every cache line
andi. r8, r6, 31 # Check if cache line boundary
bne skip_cache_ops
add r8, r4, r6 # Calculate destination address
dcbst 0, r8 # Flush data cache
icbi 0, r8 # Invalidate instruction cache
skip_cache_ops:
addi r6, r6, 4 # Next word
cmpw r6, r5 # Check if done
blt relocate_loop
sync # Ensure all stores complete
isync # Synchronize instruction fetch
# Now safe to execute relocated code
mtctr r4 # Set up to jump to relocated code
bcctr 20, 0 # Execute relocated code
Hot Code Swapping
# Atomically replace function implementation lis r3, target_function@ha addi r3, r3, target_function@l lis r4, new_implementation@ha addi r4, r4, new_implementation@l # Create branch instruction to new implementation sub r5, r4, r3 # Calculate displacement srwi r5, r5, 2 # Convert to word displacement rlwinm r5, r5, 2, 6, 29 # Position displacement in instruction oris r5, r5, 0x4800 # Create branch instruction # Atomically update stw r5, 0(r3) # Install branch to new code dcbst 0, r3 # Ensure store reaches memory sync # Memory barrier icbi 0, r3 # Invalidate old instruction isync # Synchronize instruction fetch
Performance Monitoring Code Injection
# Inject performance monitoring into hot functions lis r3, hot_function@ha addi r3, r3, hot_function@l # Save original instruction lwz r4, 0(r3) stw r4, original_instr(r0) # Create branch to instrumentation lis r5, perf_hook@ha addi r5, r5, perf_hook@l sub r6, r5, r3 # Calculate displacement srwi r6, r6, 2 # Word displacement rlwinm r6, r6, 2, 6, 29 # Position in instruction oris r6, r6, 0x4800 # Create branch instruction ori r6, r6, 0x0001 # Set link bit for call # Install instrumentation stw r6, 0(r3) # Install performance hook dcbst 0, r3 # Flush to memory sync # Ensure visibility icbi 0, r3 # Invalidate instruction cache isync # Synchronize instruction stream