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
RV32/RV64 Zifencei 2.0; 32-bit MISC-MEM encoding, opcode=0001111 and funct3=001; no explicit operands.
Standard software must zero reserved funct12, rs1 and rd; base implementations must ignore them. They are not current address or destination-register operands.
Later fetches on the same hart must observe prior data stores already visible to that hart; no concrete cache-flush implementation is prescribed.
For cross-hart publication, the writer executes a data FENCE before requesting remote FENCE.I execution; application-thread migration also matters.
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
Awaiting local fetch synchronization
Local-Hart Visibility Order
Prior data store
mem[0x00002000] = 0x00008067
FENCE.I
local inst/data synchronization point
Later instruction fetch
Awaiting local fetch synchronization

Assumes RV32+Zifencei and addresses satisfying IALIGN (C is assumed for 2-byte alignment); the complete prior word is visible to this hart, no intervening code writes occur, and fetch succeeds. Inputs are bit patterns; the stored word is not executed.

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 operands; standard software must zero funct12, rs1, and rd, and base implementations must ignore these reserved 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
  • RV32/RV64 Zifencei 2.0; 32-bit MISC-MEM encoding, opcode=0001111 and funct3=001; no explicit operands.
  • Standard software must zero reserved funct12, rs1 and rd; base implementations must ignore them. They are not current address or destination-register operands.
Semantic Check
  • Later fetches on the same hart must observe prior data stores already visible to that hart; no concrete cache-flush implementation is prescribed.
  • For cross-hart publication, the writer executes a data FENCE before requesting remote FENCE.I execution; application-thread migration also matters.

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 must zero the reserved funct12, rs1, and rd fields in the FENCE.I encoding.
For cross-hart code publication, the writer executes a data FENCE before requesting remote FENCE.I execution; applications must also account for thread migration.

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.