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
Destination rd: general-purpose register receiving the result.
Source rs1: register holding the first operand.
Immediate imm: 12-bit signed value, sign-extended before operation with rs1.
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
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
  • Confirm the current instruction format is I-type.
  • Confirm the operand order matches the example.
Semantic Check
  • Ensure the destination register usage is compatible with the calling convention.
  • Confirm this is not the lower-level form of a pseudo-instruction expansion.

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.