Skip to content

Memory-Load Slot

本页中的每个地址、字段偏移、opcode 值和字符串,均从 libtpu-0.0.40-cp314 wheel 中的 libtpu.so 按字节精确读取(BuildID md5 89edbbe81c5b328a958fe628a9f2207d,未 stripped,含完整 C++ 符号)。.text/.rodata 映射满足 VA == file offset。其他 wheel 版本会不同。

摘要

memory-load slot 是在单个 VLIW issue word 内把片上内存搬入计算寄存器文件的 bundle slot。它是 Memory-Store Slot 的读侧镜像。它不同于芯片内 DMA:DMA 通过 descriptor 在内存 tier 之间搬运块,并携带 sync flag 和 done-count;而 load slot 从某个 tier 搬运一个寄存器大小的数据到 vreg/sreg,并携带 destination register 和 sublane mask。binary 中的边界很清楚,这也是 load slot 没有 tier-selector bit 的架构原因;tier 由 op 占用的哪个 slot选择。

有三个 load tier 和四个物理落点:VMEM → vreg(vector load)、SMEM → sreg(scalar load)、CMEM → vreg(仅 Pufferfish 的专用 slot),以及 SPMEM → vreg(SparseCore tile load)。每一种都是不同的 bundle slot。单个 TensorCore load slot 是一个 discriminated union:1-/2-/3-bit sub-opcode 字段选择 addressing-mode variant(base+offset、base-only、strided、indexed/gather、circular-buffer-relative、sublane-shuffled)。逐字段 bit 位置从逐代 <Field>::GetConcatenatedValue() accessor 恢复;每个 accessor 都是一条 mov <word>; shr <shift>; and <mask> 指令,用来钉住字段在 decoded slot struct 中的精确位置。

核心的逐代故事是字段重打包:相同的逻辑字段(opcode、dest、sublane-mask、base-address、offset、stride、predication)在每一代都会移动到不同 bit 位置,并且 destination-register 字段在 v5 边界从 5 bit 加宽到 6 bit(vector register file 翻倍)。codename → slot-list 来自逐代 TensorCoreCodecBase<…Decoder, …Encoder, …> template argument 顺序;load slot 的数量以及 CMEM 是否获得自己的 slot 本身也是逐代差异。

对重新实现而言,契约是:逐代 slot-list(1/2/3 个 VMEM-load slot;CMEM slot 仅 Pufferfish)、addressing-mode sub-opcode discriminator 及其逐代取值、逐字段 word/shift/mask 布局、5→6-bit dest 加宽,以及 slot-selects-tier 模型。

Slot role将一个寄存器大小的数据从 VMEM/SMEM/CMEM/SPMEM 搬入 vreg/sreg
Tier select由占用的 slot 决定(无 tier bit)— VMEM=VectorLoad,SMEM=Scalar*,CMEM=CmemLoad(仅 PF),SPMEM=SparseCore VectorLoad
PXC VMEM-load encoderpxc::isa::TensorCoreVectorLoadEncoder::Encode @ 0x1ee287e0
PXC CMEM-load encoderpxc::isa::TensorCoreCmemLoadEncoder::Encode @ 0x1ecf89a0
Sub-opcode discriminator…VectorLoad…Opcode::Matches — PXC TensorCoreVectorLoadVmemLoadOpcode @ 0x1ee28100;V5+ TensorCoreVectorLoad0VectorLoadOpcode @ VXC 0x1f006960,GLC 0x1f3a2460,GFC 0x1f9e97e0
Field accessor shape<Field>::GetConcatenatedValue = (word@off >> shift) & mask(精确 bit 位置)
Dest field widthJF/PF 上为 5-bit,VF/GL/GFC 上为 6-bit(v5 起 vector register file 翻倍)
Register filesV0..V63(vreg,V5+ 为 64 / JF–PF 为 32),S0..S31(32 sreg),CB0..CB15(SparseCore),predicate file 15 entries(JF–PF)/ 14(V5+)— 但 slot 的 Predication field 是 5-bit,编码 preg index 外加 15=always / 31=never sentinel

Load Slot 是逐代 VLIW Sub-Bundle

每一代的 TensorCore bundle 都是固定位置 slot 组成的 struct;slot 顺序是逐代 TensorCoreCodecBase<TensorCoreBundle, …Decoder, …Encoder, …> 的 template-argument 顺序。load slot 的数量,以及 CMEM 是否拥有专用 slot,是主要的逐代差异。CMEM 只在 Pufferfish 上是一等对象(它有自己的 bundle slot);Viperfish/Ghostlite/6acc60406 完全没有 *Cmem* ISA op family,并将释放出的 bundle 宽度复用于第 2/第 3 个 VMEM-load slot。

GenVMEM-load slots (TC)CMEM-load slotsSMEM scalar-load slots
Jellyfish1(slot-mask bit 0x04002(scalar_0/scalar_1
Dragonfish1(= Jellyfish codec)02
Pufferfish1(VectorLoad1(CmemLoad,专用)2(Scalar0/Scalar1
Viperfish3(VectorLoad0/1/202(ScalarAlu0/ScalarAlu1
Ghostlite2(VectorLoad0/102(ScalarAlu0/ScalarAlu1
6acc604062(VectorLoad0/102(ScalarAlu0/ScalarAlu1

在 Pufferfish 上,VectorLoad slot 的 control fields 落在绝对 bundle bits 119..140(VectorLoadEncoder::Encode body @ 0x1ee287e0 通过 BitCopy(dst, 136, …, 5) 写 Predication,Dest BitCopy(dst, 129, …, 5),Stride …126,3,Offset …124,2,BaseAddress …122,2,SublaneMask …119,3,Opcode …134,2);CmemLoad control fields 落在 103..118(CmemLoadEncoder::Encode body @ 0x1ecf89a0 写 Predication BitCopy(dst,114,5),Opcode …113,1,SublaneMask …110,3,BaseAddress …108,2,Offset …106,2,Stride …103,3)— 见 Pufferfish 51B Bundle。两个 control region 互不重叠,所以一个 CMEM load 和一个 VMEM load 可以在同一个 bundle cycle 中 issue;这是唯一具备此性质的世代(它们共享的 Vs0/Vs1/Vs2Imm 字段落在更高且互不重叠的 bits 241..256+)。Viperfish 上的三个 VMEM-load slot 由三个不同的 per-slot encoder 符号 vxc::isa::TensorCoreVectorLoad{0,1,2}Encoder::Encode 确认。

NOTE — CMEM 在 Pufferfish 上需要自己的 slot 的架构原因,正是 load slot 的 wire encoding 不携带 tier selector(见 The Slot-Selects-Tier Model)。要在同一 cycle 读取 CMEM 和 VMEM,就需要两个物理不同的 slot。v5 去掉 CMEM 后,该 slot 被移除,宽度转给额外的 VMEM-load slot。


VMEM-Load Encoder Algorithm(VectorLoadEncoder::Encode

Pufferfish VMEM-load slot 由 pxc::isa::TensorCoreVectorLoadEncoder::Encode(TensorCoreVectorLoad const&, Span<uint8>)0x1ee287e0)打包;它是 cmem_load Encode 的读侧镜像。与每个 Pufferfish slot 一样,它通过对共享 bit-packing primitive BitCopy(buf, abs_bit, &field, src_bit=0, nbits)0x1fa0a900)的一次调用写入每个字段,并且 dst_bit 参数就是字面量绝对 bundle bit,不需要反推 shift 算术(见 Pufferfish 51B Bundle §The Direct-BitCopy Model)。该结构从反汇编按字节精确得到:predication 从 proto[+0x1c] 暂存并先被无条件写入,然后 proto[+0x50] 处的 oneof discriminator 通过 self-relative jump table(lea -0x135e338d(%rip),%rcx → table base 0xb8454a4cmp $0x9,%rax; ja <out-of-range>)选择十种行为之一,VmemLoad issue arm 重放下面的字段序列,每个字段由 TensorCoreVectorLoad_VmemLoad_globals_ submessage(0x22410b00)上的 per-field has-bit gate:

c
// pxc::isa::TensorCoreVectorLoadEncoder::Encode(proto, buf)  @ 0x1ee287e0  (decoded byte-exactly)
pred = proto[+0x1c];                            // movslq 0x1c(%rsi)
BitCopy(buf, 136, &pred, 0, 5);                 // Predication @136/5 — written first, unconditionally
tag = proto[+0x50];                             // oneof discriminator; jump table over tags 0..9
if (tag > 9) abort();                           // cmp $0x9; ja  -> out-of-range trap
// dispatch via table @ 0xb8454a4 ; tag 5 (Noop) forces pred=31, tag 6 is the VmemLoad issue arm:
if (tag == NOOP) { pred = 31; BitCopy(buf, 136, &pred, 0, 5); return OK; }   // kNeverExecute
// ---- VmemLoad issue arm (tag 6): inner = the VmemLoad submessage (or _globals_ default if clear) ----
inner = proto[+0x48];                           // VmemLoad submessage
BitCopy(buf, 134, &Opcode, 0, 2);               // Opcode @134/2 — addr-mode discriminator
if (inner.has[0x10] & 0x01) BitCopy(buf, 129, &inner.Dest,        0, 5);  // Dest vreg @129/5
if (inner.has[0x10] & 0x02) BitCopy(buf, 126, &inner.Stride,      0, 3);  // Stride @126/3  (off +0x1c)
if (inner.has[0x10] & 0x04) BitCopy(buf, 124, &inner.Offset,      0, 2);  // Offset @124/2  (off +0x20)
if (inner.has[0x10] & 0x08) BitCopy(buf, 122, &inner.BaseAddress, 0, 2);  // BaseAddress @122/2 (off +0x24)
if (inner.has[0x10] & 0x10) BitCopy(buf, 119, &inner.SublaneMask, 0, 3);  // SublaneMask @119/3 (off +0x28)
// ----- shared operand pool (co-allocated across slots; abs 241/246/251 + 16-bit imms) -----
if (inner.has[0x10] & 0x20) BitCopy(buf, 251, &inner.Vs2, 0, 5);   // Vs2 register selector
if (inner.has[0x10] & 0x40) BitCopy(buf, 246, &inner.Vs1, 0, 5);   // Vs1
if (inner.has[0x10] & 0x80) BitCopy(buf, 241, &inner.Vs0, 0, 5);   // Vs0  (dest VREG / base)
if (inner.has[0x11] & 0x01) BitCopy(buf, 304, &inner.Imm, 0, 16);  // shared immediate word
if (inner.has[0x11] & 0x02) BitCopy(buf, 288, &inner.Imm, 0, 16);  // shared immediate word
if (inner.has[0x11] & 0x04) BitCopy(buf, 272, &inner.Imm, 0, 16);  // shared immediate word
if (inner.has[0x11] & 0x08) BitCopy(buf, 256, &inner.Imm, 0, 16);  // shared immediate word

dst-bit 常量直接来自每次 call 1fa0a900 <BitCopy> 前的 mov $imm,%esi0x88=136(pred)、0x86=134(opcode)、0x81=129(dest)、0x7e=126(stride)、0x7c=124(offset)、0x7a=122(base)、0x77=119(sublane),以及 shared-pool 0xfb=251 / 0xf6=246 / 0xf1=241(Vs2/Vs1/Vs0,w5)和 0x130=304 / 0x120=288 / 0x110=272 / 0x100=256(immediates,w16)。它们与下面的 dedicated-region map 以及 cmem-load slot 的高位 shared pool(Vs 在 241/246/251,immediates 在 256/272/288/304 — 见 cmem_load §The Shared Operand Pool)逐 bit 一致,确认这两个 memory-read slot 从同一个物理 Y-register/immediate pool 取数。

NOTE — predication 在 tag 被读取之前就已写入。 encoder 暂存 proto[+0x1c],并在加载 proto[+0x50] oneof discriminator 之前发出 @136/5 predication BitCopy。因此 empty(tag-0)或 Noop(tag-5)slot 仍会携带一个 5-bit predication 值;idle encoding 为 31kNeverExecute),与 cmem_load slot 完全一致。两个 memory-read slot 共享这种 idle-encoding 约定;清零的 bundle buffer 不是 idle marker(predicate 0 是 live op)。

QUIRK — oneof 覆盖十个 arm,而不是三个。 discriminator 上的 cmp $0x9,%rax; ja 边界意味着 VMEM-load oneof 最多有十个 tag(0..9),而 cmem_load slot 只有三个(0/5/6)。额外 arm 是 addressing-mode variant(VmemLoadVmemLoadShuffledVmemLoadIndexedIar0/1)加上 empty/Noop idle 形式;每个都是不同的 jump-table arm,会用不同的 @134 Opcode 常量重放同一个 BitCopy 字段序列。重新实现者必须把 discriminator 设为 10 个 arm,并让每个 non-idle arm 都通过相同 field map;addressing mode 之间只有 @134 的 2-bit Opcode 值不同。


Load Op List(Addressing-Mode Sub-Opcodes)

每个 load slot 都是一个 discriminated union;sub-opcode 字段选择 addressing-mode variant。各 family 的 variant:

PXC TensorCore VectorLoad(VMEM → vreg) — byte @0x18 bits 6-7(mask 0xC0)处的 2-bit sub-opcode。discriminator 是 TensorCoreVectorLoadVmemLoadOpcode::Matches(@ 0x1ee28100,body (*((_BYTE*)this + 24) & 0xC0) == 0)中的字面 (byte@0x18 & 0xC0) 测试:

valuevariant含义
00VmemLoadbase + immediate offset
010x40VmemLoadShuffledbase + offset,加载时 sublane shuffle
100x80VmemLoadIndexedIar0通过 index-address-register 0 gather
110xC0VmemLoadIndexedIar1通过 index-address-register 1 gather

PXC TensorCore CmemLoad(CMEM → vreg) — byte @0x16 bit 1 处的 1-bit sub-opcode(TensorCoreCmemLoadCmemLoadOpcode::Matches @ 0x1ecf8800,body (*((_BYTE*)this+22) & 2) >> 1);当 word @0x10 的 bits 0x7c000000000000 全部置位时,Noop(slot-idle)variant 匹配;其 Matches(@ 0x1ecf87e0)为 (~word@0x10 & 0x7c000000000000) == 0

PXC TensorCore Scalar1 ScalarLoadSmem(SMEM → sreg) — word @0x30 bits 50-55(mask 0xfc000000000000)处的 6-bit opcode。ScalarLoadSmemOpcode::Matches(@ 0x1ed27c60)测试 (word@0x30 & 0xfc000000000000) == 0x10000000000000(value 0x4ScalarLoadSmem);value 0x5ScalarLoadSmemOffsetSreg ← SMEM[Sreg+imm])。

VXC/GLC/GFC TensorCore VectorLoad0/1/2(VMEM → vreg) — multi-bit sub-opcode(位置见下)。Variant:VectorLoad(base+offset)、VectorLoadBase(仅 base reg,无 offset)、VectorLoadShuffled / VectorLoadShuffledBase(加载时 shuffle)、VectorLoadIndexed0/1(通过 IAR0/IAR1 gather)、ReadIar0 / ReadIar1(把 index-address-register 读入 vreg 以暂存 gather),以及 Compact_* 形式(Compact_VectorLoadCompact_ReadIar0/1Compact_VectorLoadIndexed0/1Compact_VectorLoadShuffled),当字段适配时可将 load 打包进更窄 slot。

VXC/GLC/GFC ScalarAlu1 ScalarLoadSmemScalarLoadSmemYSreg ← SMEM[Y imm])和 ScalarLoadSmemXYSreg ← SMEM[X base-Sreg + Y imm])。

SparseCore(vfc / glc::sparsecore / gfc::sparsecore)VectorLoad(SPMEM → vreg)TileSpmemLoad(base+offset)、TileSpmemLoadCircularBuffer(CB-register-relative)、TileSpmemIndexedLoad(通过 Index gather)、TileSpmemIndexedLoadCircularBuffer(indexed + CB)。包含丰富 predication(NormalPredicationRotatePredicationIsRotatePredicationPredicationInversion)。

scalar/SparseCore/BarnaCore load 的 MC-layer mnemonic(TensorCore VMEM/CMEM load 经由 proto codec,而不是 MC table)记录在 MC-Emitter 页面:SLDi/SLDri/SLDrr(TC scalar)、scVLD*/scSLD*/scSLDCBREG* family(SparseCore),以及 bcVLDi/bcVLDr/bcVLD_aliaddr{i,r}(BarnaCore)。


Bit-Field Layout(已解码的 GetConcatenatedValue Accessors)

每个逐代 Field class 都暴露 GetConcatenatedValue(),其 body 字面上就是 (word@off >> shift) & mask,因此字段的精确位置可直接从反汇编读取,无需推断。slot struct 在固定 member offset(取决于 slot,@0x10@0x18@0x20@0x30@0x40)处以 64-bit word 保存原始 bundle bits。下面的偏移是 decoded slot struct 内部的 slot-relative member-word offsets(member-word @byte, shift, mask → width)。Pufferfish load slot 的 bundle-absolute bit(abs 119..140)位于 Pufferfish 51B Bundle 页面。

Pufferfish (PXC) — TensorCore VectorLoad(VMEM → vreg)

DestField::GetConcatenatedValue(@ 0x1ee281a0)按字节精确为:(*((_DWORD*)this + 6) >> 1) & 0x1F,即 member offset 24(@0x18)处的 DWORD,右移 1,并 mask 到 5 bit。

Fieldwordshiftmaskwidth含义
Opcode@0x1860x32addr-mode discriminator
Dest (vreg)@0x1810x1f5destination vreg
SublaneMask@0x10(128-bit)620x73sublane-group select(跨入 @0x18
BaseAddress@0x10600x32base-address reg select
Offset@0x10580x32immediate-offset slot index
Stride@0x10550x73stride select
Vs0 / Vs1 / Vs2@0x2059 / 54 / 495-bit5vector source ports(gather index)
Imm2..Imm5@0x2e/@0x2c/@0x2a/@0x2816-bit16immediate displacement slots
Predication(独立 Predication slot)50..14 preg / 15 always / 31 never

IndexedIar0/IndexedIar1/Shuffled variant 共享这些精确位置;只有 2-bit Opcode 值变化(VmemLoad=0,VmemLoadShuffled=1,VmemLoadIndexedIar0=2,VmemLoadIndexedIar1 通过专用 branch)。Shuffled 增加 ShuffleField(sublane-shuffle selector);Indexed variant 使用 Vs0/Vs1/Vs2 作为逐 lane gather index。Accessor anchors:Opcode::Matches @ 0x1ee28100DestField @ 0x1ee281a0SublaneMaskField @ 0x1ee281c0BaseAddressField @ 0x1ee281e0OffsetField @ 0x1ee28200StrideField @ 0x1ee28220Vs0Field @ 0x1ee28240Vs1Field @ 0x1ee28260Vs2Field @ 0x1ee28280。三个 source port(Vs0/Vs1/Vs2)是 Pufferfish 上逐代稳定的计数;load slot 在 v4 尚未加宽其 gather-index port count;v5+ 可见的加宽体现在 load slot 数量,而非每 slot port count。

Pufferfish (PXC) — TensorCore CmemLoad(CMEM → vreg)

CMEM load 在字段上一一镜像 VMEM load,但位于独立的 CmemLoad slot/word:Opcode @0x16 bit 1(1-bit),Predication @0x10>>50 &0x1f,SublaneMask @0x10>>46 &0x7,BaseAddress @0x10>>44 &0x3,Offset @0x10>>42 &0x3,Stride @0x10>>39 &0x7,并且与 VMEM load 完全一样,拥有三个 gather index port:Vs0 @0x20>>59、Vs1 @0x20>>54 &0x1f、Vs2 @0x20>>49 &0x1f,外加相同的 Imm2..Imm5 16-bit slots。Anchors:NoopOpcode::Matches @ 0x1ecf87e0CmemLoadOpcode @ 0x1ecf8800PredicationField @ 0x1ecf8820Vs0Field @ 0x1ecf88c0Vs1Field @ 0x1ecf88e0Vs2Field @ 0x1ecf8900

Viperfish (VXC) — TensorCore VectorLoad0(VMEM → vreg)

discriminator 是两个测试,在 VectorLoadOpcode::Matches(@ 0x1f006960)中按字节精确:(*((_BYTE*)this + 25) & 0xC) == 0(byte @0x19 bits 2-3,即 qword @0x18 bits 10-11,mask 0xc00以及 (~*((_QWORD*)this + 2) & 0x3800000000000000) != 0(word @0x10 的 high-word 测试,选择 Iar/Indexed family)。VectorLoadBaseOpcode 匹配 0x400VectorLoadShuffledOpcode 匹配 0x800

Fieldwordshiftmaskwidth含义
Dest (vreg)@0x1840x3f6destination vreg(V0..V63)
SublaneMask@0x1800xf4sublane-group select
Predication@0x18120xf4predicate reg(0..15)
Stride@0x10550xf4stride select
Offset@0x10590x73immediate-offset slot index
BaseAddress (Indexed)@0x10620x32base-address reg select

DestVregField::GetConcatenatedValue(@ 0x1f006b60)读取 (*((_DWORD*)this + 6) >> 4) & 0x3F,这是 6-bit dest 的字节精确证据。ReadIar0/Iar1 只携带一个 DestVreg(IAR 值落入 vreg)。Anchors:PredicationField @ 0x1f006ac0StrideField @ 0x1f006b80SublaneMaskField @ 0x1f006ba0OffsetField @ 0x1f006bc0

Ghostlite (GLC) — TensorCore VectorLoad0(VMEM → vreg)

GLC 将相同逻辑字段重打包到与 VXC 不同的位置。discriminator 是 (*((_QWORD*)this + 3) & 0x6000) == 0(word @0x18 bits 13-14)加上 high-word (word@0x10 >> 62) & 7 测试,在 VectorLoadOpcode::Matches(@ 0x1f3a2460)中按字节精确。

Fieldwordshiftmaskwidth
Dest (vreg)@0x1870x3f6
SublaneMask@0x1830xf4
Predication@0x18150xf4
Stride@0x10580xf4
BaseAddress (Indexed)@0x1810x32
Offset@0x10/@0x18(3-bit straddle)3

相较 VXC:Dest 从 bit 4 移到 7,SublaneMask 从 bit 0 移到 3,Predication 从 bit 12 移到 15,Stride 从 bit 55 移到 58,BaseAddress 从 word @0x10 bit 62 移到 word @0x18 bit 1。这是纯粹的逐代 layout delta;字段相同,位置不同。Anchors:DestVregField @ 0x1f3a26a0StrideField @ 0x1f3a26c0SublaneMaskField @ 0x1f3a26e0

6acc60406 (GFC) — TensorCore VectorLoad0(VMEM → vreg)

GFC 使用更宽的 opcode。discriminator 是 (*((_BYTE*)this + 25) & 0x18) == 0(byte @0x19 bits 3-4)加上 word @0x10 & 0x7000000000000000(bits 60-62)中的 3-bit opcode,在 VectorLoadOpcode::Matches(@ 0x1f9e97e0)中按字节精确。3-bit opcode(相对 GLC 的 2-bit)与 GFC 添加 op 的事实一致。

Fieldwordshiftmaskwidth
Dest (vreg)@0x1850x3f6
SublaneMask@0x1810xf4
Stridebyte @0x1700xf4
Offset@0x10600x73

6acc60406(GFC)把 Stride 移入 byte @0x17,这是另一个逐代 layout delta。Anchors:DestVregField @ 0x1f9e99e0StrideField @ 0x1f9e9a00SublaneMaskField @ 0x1f9e9a20OffsetField @ 0x1f9e9a40

PXC / VXC scalar-load(SMEM → sreg)

PXC Scalar1 ScalarLoadSmem:Opcode @0x30>>50 &0x3f0x4=Smem,0x5=SmemOffset),Address @0x30>>39 &0x3f,Dest(sreg)@0x30>>34 &0x1f,Imm0 @0x30>>18 &0xffff。VXC ScalarAlu1 ScalarLoadSmemY/XY(从 accessor 按字节精确得到):Opcode @0x40 & 0xFC00000x40000=SmemY → value 1,0x80000=SmemXY → value 2),Dest @0x40>>2 &0x1f0x1eedc280),Y @0x40>>7 &0x3f0x1eedc2a0),X @0x40>>13 &0x1f0x1eedc2e0)。GLC/GFC 使用 gxc::glc/gxc::gfc analogues;GFC 还额外添加 SmemFetchAndAdd


Addressing Modes

sub-opcode 选择六种 addressing mode 之一:

  1. Base + immediate offsetVmemLoad / TileSpmemLoad):addr = base_reg + offset_immbase_reg 是 base-address register 的 2-bit selector;offset 是进入 bundle 共享 immediate slot 的小型(2-/3-bit)index,这些 slot 保存 16-bit displacement word(Imm2..Imm5)。
  2. 仅 Base registerVectorLoadBase,VXC/GLC/GFC):没有 offset 字段。
  3. StridedStrideField(3-/4-bit)选择 stride;load 以该 stride 读取 N 个 sublane。
  4. Indexed / gatherVmemLoadIndexedIar0/1VectorLoadIndexed0/1TileSpmemIndexedLoad):逐 lane 地址来自 index-address register(IAR)或 Vs operand。ReadIar0/ReadIar1 先把逐 lane index 暂存到 IAR;随后 Indexed load gather VMEM[base + IAR[lane]]。PXC 使用 Vs0/Vs1/Vs2 作为 index port;VF/GL/GF 使用 IAR0/IAR1。
  5. Circular-buffer relative(仅 SparseCore):CB register(CB0..CB15)保存滚动 base;TileSpmemLoadCircularBuffer 相对它读取,并可选择自动更新 pointer。
  6. Sublane-shuffledVmemLoadShuffled / VectorLoadShuffled):load 在加载过程中应用 sublane permutation(ShuffleField),把 load + sublane-shuffle 融合进一个 slot。

indexed IAR port 与 store slot 共享:store 的 SetIar* sub-op 设置的 IAR 可由后续 indexed load 消费(见 Memory-Store Slot)。逐代 IAR 数量是 Target::IarsPerTensorCore()


Slot-Selects-Tier Model {#the-slot-selects-tier-model}

load slot 内部没有 tier-select bit。tier 由 op 占用的 slot 选择:

Source tierSlot
VMEMVectorLoad / VectorLoad0/1/2
CMEM专用 CmemLoad slot(仅 Pufferfish)
SMEMScalar0/1(PXC)或 ScalarAlu0/1(VF/GL/GF),opcode ScalarLoadSmem*
SPMEMSparseCore VectorLoad slot,opcode TileSpmemLoad*

这是 MemorySpace Enum 的规范伴随模型:LLO operand 携带的运行时 MemorySpace 在 IR 层选择 tier,逐代 lowering 将它路由到匹配 slot;随后 slot 的 wire encoding 只携带地址(tier-relative byte offset 除以 tier granule)、base-address register 以及 offset/stride。bundle word 中的三 bit 无法编码 17 个 MemorySpace 值,这正是由 slot identity 而不是 tag 承载 tier 的原因。


Load Granularity

SublaneMask 字段控制 load granularity。一个 vector register 保存 lane_count × sublane_count 个元素;mask 选择该 load 写入哪些 sublane group。PXC SublaneMask 是 3-bit(8 个可选 group);VXC/GLC/GFC 将其加宽到 4-bit(16 个 group)。SparseCore 使用 MaskFieldscVLD_MSK family)外加 _NP(no-predicate)和 _PASS(masked-out lane passthrough)modifier。没有独立 count 字段:granularity 是 SublaneMask 的 popcount,而 addressing mode(strided vs contiguous)决定触碰多少 memory word。默认(所有 sublane)是 full-vector load;Shuffled variant 还会在加载时置换 sublane。


Destination Register File 和 5→6-Bit 加宽

来自 TPURegStrings:vector V0..V63(64 vregs;多寄存器 load 的 wide pairs/triples/quads 如 V60_V61V60_V61_V62_V63 存在)、scalar S0..S31(32 sregs)、circular-buffer CB0..CB15(16,SparseCore)、predicate P0..P31(32)。vector-load Dest 字段在 Pufferfish 上为 5-bit(字节精确 (DWORD@0x18 >> 1) & 0x1f0x1ee281a0),在 Viperfish/Ghostlite/6acc60406 上为 6-bit(字节精确 (DWORD@0x18 >> 4) & 0x3f0x1f006b60)。v5 边界的 dest 加宽 5 → 6 bits 是主要逐代差异,对应翻倍的 vector register file。scalar-load Dest 每一代都是 5-bit。

GOTCHA — 5-bit PXC dest 在 slot 中直接寻址 V0..V31;更宽的 V32..V63 半区以及 wide/complement multi-vreg destination(V60_V61_V62_V63 quads)通过独立的 wide/complement 机制到达,而不是通过加宽 slot 字段。multi-register destination 的 slot encoding 此处未解码。


Per-Gen Load Encoding Table(汇总)

DimensionJellyfish/DragonfishPufferfish (PXC)Viperfish (VXC)Ghostlite (GLC)6acc60406 (GFC)
Bundle width41 B51 B64 B64 B64 B
Codec namespacejellyfish::isapxc::isavxc::isagxc::glc::isagxc::gfc::isa
VMEM-load slots1(slot-mask 0x0401(VectorLoad3(VectorLoad0/1/22(VectorLoad0/12(VectorLoad0/1
CMEM-load slotnone1(CmemLoadnonenonenone
VMEM addr-mode opcode(InstBits)2-bit @ 0x18 bit6-7bits 10-11(0xc00)+hi-wordbits 13-14(0x6000byte0x19&0x18 + 3b@60-62
VMEM Dest field(InstBits)5-bit @ 0x18 bit16-bit @ 0x18 bit46-bit @ 0x18 bit76-bit @ 0x18 bit5
VMEM SublaneMask(InstBits)3-bit(straddle)4-bit @ 0x18 bit04-bit @ 0x18 bit34-bit @ 0x18 bit1
VMEM Stride(InstBits)3-bit @ 0x10 bit554-bit @ 0x10 bit554-bit @ 0x10 bit584-bit @ byte 0x17
VMEM Offset(InstBits)2-bit @ 0x10 bit583-bit @ 0x10 bit593-bit(straddle)3-bit @ 0x10 bit60
VMEM BaseAddress(InstBits)2-bit @ 0x10 bit602-bit @ 0x10 bit622-bit @ 0x18 bit1(3b opcode region)
VMEM Predication5-bit(15 preg)5-bit(sep. slot)4-bit @ 0x18 bit124-bit @ 0x18 bit154-bit
SMEM-load opEmitScalarLoadScalarLoadSmem(+Offset)ScalarLoadSmemY/XYScalarLoadSmemY/XY…Y/XY(+FetchAndAdd)
Gather index sourcen/a(no IAR)Vs0/Vs1/Vs2IAR0/IAR1(ReadIarIAR0/IAR1IAR0/IAR1
SparseCore loadnonenone(BarnaCore bcVLDTileSpmem*(vfc)TileSpmem*(glc::sc)TileSpmem*(gfc::sc)

Jellyfish/Dragonfish vector-load 使用 monolithic VectorLoadInstruction proto,由 EncoderJf 打包进 41-byte bundle 外加 LLVM InstBits table;slot presence(slot-mask bit 0x040)、dest-vreg semantics 和 sublane-shuffle variant 已确立,但精确 JXC bit offsets 位于 InstBits(codec 路径中磁盘上全零的 binary record)而不是 Field accessor 中,因此这里未逐 bit 枚举。


尚未钉住的内容

  • Jellyfish/Dragonfish 精确 VMEM-load bit 位置。 Slot presence、dest semantics 和 sublane-shuffle variant 已确立;逐字段 offset 位于 InstBits,而不是 Field accessor。
  • Offset→immediate-slot 映射。 2-/3-bit Offset 是 slot index;16-bit displacement 位于 Imm2..Imm5;逐 opcode 的 Offset→Imm 映射尚未完整枚举。
  • IAR file sizeReadIar0/Iar1 暗示每 slot 2 个 IAR;register-file count IarsPerTensorCore() 数值尚未在此恢复)。
  • wide/complement multi-vreg load destination encodingV60_V61_V62_V63 quads)。
  • bundle 内每个 load slot 的字面 byte-range。 decoded slot struct 内的 field word offset 已钉住;绝对 Pufferfish load-slot region(abs 119..140)位于 Pufferfish 51B Bundle 页面,但 V5+ 的逐代 slot-to-byte map 来自各 codec 的 Encode dispatch。