FENCE.I

RISC-V FENCE.I Instruction Details

Instruction ManualI-type

Synchronizes data stores and later instruction fetches on the current hart, so fetches after FENCE.I can observe prior visible code writes.

Instruction Syntax

fence.i
Operand Breakdown
FENCE.I has no explicit assembly operands; it is not an ordinary I-type computation with an rs1 operand or variable immediate.
funct12, rs1, and rd are reserved for future finer-grain fences; standard software must zero them rather than interpreting them as current assembly operands.
FENCE.I synchronizes the current hart's prior visible data stores with later instruction fetches; it is not an ordinary data-memory FENCE or TLB invalidation.
ZifenceiCache & Sync

Instruction Behavior

FENCE.I is a Zifencei MISC-MEM instruction (opcode=0001111, funct3=001) with no explicit operands. It synchronizes the current hart's instruction and data streams: instruction fetches initiated after FENCE.I must observe data stores already visible to that hart before FENCE.I. It is used for self-modifying code, dynamic code generation, and JIT code publication. FENCE.I is not the ordinary data-memory FENCE, not a TLB invalidation, and not a concrete instruction-cache flush; cross-hart code updates require corresponding synchronization on the other harts.

FENCE.I Decode And Instruction-Fetch Sync Animation

Shows the fixed Zifencei MISC-MEM encoding and the ISA-visible local-hart synchronization between prior data stores and later instruction fetches.

no explicit operands
fence.ifence.i
Execution Context

These inputs only form a code-update example; FENCE.I itself has no explicit address or code-value operands. Two-byte alignment permits IALIGN=16 fetches when the C extension is present.

31..20
19..15
14..12
11..7
6..0
000000000000
funct12=0
00000
rs1=x0
001
funct3
00000
rd=x0
0001111
opcode
Fetch Sync Path
instruction
0x0000100F
opcode
0001111 -> MISC-MEM
funct3
001 -> FENCE.I
fixed fields
funct12=0, rs1=x0, rd=x0
prior store
mem[0x00002000] = 0x00008067
fence.i
order prior visible stores before later fetches
later fetch
fetch PC 0x00002000 -> 0x00008067
Local-Hart Visibility Order
Prior data store
mem[0x00002000] = 0x00008067
FENCE.I
local inst/data synchronization point
Later instruction fetch
PC 0x00002000 -> 0x00008067

This animation shows only the Zifencei ISA-visible local-hart synchronization semantics; it does not model concrete I-cache, D-cache, pipelines, branch prediction, fetch latency, or cross-hart shootdown protocols.

Quick Understanding & Search Notes

FENCE.I is the current-hart synchronization point for “write code, then fetch code”: after data stores write new instructions, FENCE.I ensures later instruction fetches observe those visible writes.

FENCE.I has no explicit assembly operands; standard software should zero reserved funct12, rs1, and rd fields.
Its guarantee is current-hart synchronization between prior visible data stores and later instruction fetches, not ordinary data-memory ordering.
Cross-hart code updates require additional mechanisms so the other harts perform corresponding fetch synchronization.
Do not read FENCE.I as a TLB flush, address-translation fence, fixed cache-line operation, or concrete microarchitectural behavior.

Common Usage Scenarios

Self-modifying Code

Understand this scenario with real code like «fence.i # sync instruction fetch with prior data stores».

JIT Compilation

Understand this scenario with real code like «fence.i # sync instruction fetch with prior data stores».

Dynamic Code Generation

Understand this scenario with real code like «fence.i # sync instruction fetch with prior data stores».

Pre-Use Checklist

Syntax Check
  • Verify the immediate field is within the valid range.
  • Confirm source register rs1 points to the correct operand.
Semantic Check
  • Check if the immediate sign-extension matches expectations.
  • Ensure the result register rd has a clear purpose.

Pitfalls / Common Confusions

FENCE.I synchronizes only the current hart's instruction and data streams; it does not automatically make other harts fetch the new code.
FENCE.I is not ordinary FENCE, not TLB invalidation, and not the same as a concrete implementation's instruction-cache flush.
Standard software should zero the reserved funct12, rs1, and rd fields in the FENCE.I encoding.
Self-modifying code, JITs, or dynamically generated code need FENCE.I in the correct synchronization sequence before execution on the current hart.

FAQ

Is FENCE.I the same as FENCE rw,rw?

No. FENCE constrains visible ordering of data-memory and I/O operations; FENCE.I synchronizes the instruction-fetch path with prior data stores.

Does FENCE.I automatically synchronize all harts?

No. The official semantics are local to the current hart; multi-hart code modification needs corresponding synchronization on the other harts too.

Is FENCE.I an instruction-cache flush?

Do not read it that way. The specification defines instruction/data stream synchronization, not a concrete cache structure, flush algorithm, or latency.