解码侧:VF / GXC
本页中的每个偏移、值和地址都从
libtpu-0.0.40-cp314wheel 中的libtpu.so逐字节读取而来(libtpu-0.0.40-cp314-cp314-manylinux_2_31_x86_64/libtpu/libtpu.so,BuildID md589edbbe81c5b328a958fe628a9f2207d,未 strip — 完整 C++ 符号;.text和.rodata以 1:1 映射,VA == file offset)。其他 wheel 版本会有差异。
摘要
本页记录三个 V5+ TensorCore MXU 编码器的反汇编器逆向路径:Viperfish(TPU v5,命名空间 vxc)、Ghostlite(TPU v6 lite / cloud v6e,gxc::glc),以及 6acc60406 系列(cloud TPU7x,gxc::gfc)。它是 JF / PF 解码侧 页面的 V5+ 对应篇:Jellyfish 用两级 opcode switch 解码,Pufferfish 引入 staged-copy 的 Opcode::Matches 扫描;三个 V5+ 世代都使用同一个扫描机制,没有其他解码路径。本页从解码侧证明每个编码侧 bit 位置,命名两个此前仅推断出的 Viperfish latch 控制字段,并修正跨世代 MXU1 twin 几何关系。
解码机制是统一的,并且是 V5+ BitCopy 编码模型的逆过程。TensorCoreVectorExtended0Decoder::Decode 把最多 9 个 bundle 字节 staging 到一个 scratch struct 中(offset 0 处有 size-tag 1,offset 8 处放 bundle 字节 — v10 = 9; if (len < 9) v10 = len),先通过 …PredicationField::GetConcatenatedValue 读取 predication 字段,然后按固定顺序线性扫描每个 opcode 的 Opcode::Matches 谓词。每个 Matches 都是在 staged quadword 上做 mask/value 测试;每个操作数的 …Field::GetConcatenatedValue 都是一个 shift & mask 访问器。因为 bundle 字节位于 staged offset 8,读取 struct offset 8 处 staged quadword 并右移 S 的访问器就是直接读取绝对 bundle bit S — 这就是为什么解码侧 shift 与编码侧 BitCopy dst_bit 参数一一相等。
V5+ 最重要的结构事实是 −N MXU1 twin:两个 VectorExtended slot 的控制区域相差固定 bit 偏移,解码侧证明并修正了该偏移。Viperfish 的 MXU1 相对 MXU0 是 −20;Ghostlite 是 −21;而 6acc60406 系列是 −25 — 不是早先跨世代表从 Ghostlite 沿用的 −21。原因是 6acc60406 的 MXU0 控制区域比 Ghostlite 上移 +4 bit,而 MXU1 在两个 GXC 世代中都锚定在同一个绝对 bit 39,因此 slot 间 delta 增大了 4。解码侧还解析了编码侧分析中仅作推断的两个 Viperfish latch 控制 bit:abs 57 是 Transpose 字段,abs 58 是 Target(matrix-staging-register 选择)字段 — 两者都由解码器的 …TransposeField / …TargetField 访问器直接命名,并追踪到其 MLIR 生产者。
对重新实现而言,契约是:
- V5+ 解码机制:
Decoder::Decode→ staged copy(stage[0]=1,bundle 字节位于stage+8)→GetConcatenatedValuepredication 读取 → 线性Opcode::Matches扫描,是编码侧BitCopy的逐字节精确逆过程。 - Viperfish 的逐字段 bit map 及其 −20 twin:每个控制字段和 predication 字段都从 MXU0 到 MXU1 精确移动 −20;八个 register-operand selector 不移动(共享池)。
Transpose(abs 57)/Target(abs 58) latch 字段及其 producer→encoder→decoder 链。- GXC dtype-class 解码:glc 的统一 8-bit-opcode latch 判别器、float/int dtype-class 矩阵、仅 float 的
6acc60406(gfc)集合,以及修正后的 −21(glc)/ −25(gfc) twin。
| VF 解码器入口 | TensorCoreVectorExtended0Decoder::Decode @ 0x1ef6e4c0 (MXU0), …Extended1Decoder::Decode @ 0x1efb9760 (MXU1) |
| VF stage | *(qword)stage = 1; memcpy(stage+8, span, min(len,9)); 先读 predication,边界 < 0x10 |
| VF latch opcode | abs 59 w5(Pushmatrix*,所有 dtype 的 value 均为 14),data-format abs 51 w4 |
| VF matmul opcode | abs 57 w7(MatrixMultiply*,0x2 Msra / 0x3 Msrb),MatmulDataFormat abs 51 w4 |
| VF Transpose / Target | abs 57 / abs 58(…PushmatrixBf16TransposeField 0x1ef9db00 / …TargetField 0x1ef9db20) |
| VF twin | −20(控制字段 + predication;8 个 operand selector 为 delta-0) |
| glc 解码器 | …Extended0Decoder::Decode @ 0x1f2f69a0; opcode abs 60 w6,dtype-class abs 54 w2 |
| gfc 解码器 | …Extended0Decoder::Decode @ 0x1f96d020(gxc::gfc = 6acc60406 / cloud TPU7x);opcode abs 64 w6,dtype-class abs 59 w2,bit-62 guard |
| GXC twins | glc −21,gfc −25(MXU0 从 glc→gfc 漂移 +4;MXU1 在两者中都锚定于 abs 39) |
| MSR 数量 | JF 1,PF 1,VF 2,glc 2(xla::jellyfish::*Target::MatrixStagingRegisterCount 0x1d490340/…4949e0/…49ace0/…497ae0) |
| 编码侧校验 | GXC encoder CreateEncoderGlGf @ 0x1e831020(GL/GF 共享);VF/GL/GF bundle = 64B,运行时 field[32]/field[31] 通过 GetTileInstructionBundleSizeInBytes @ 0x1395b8e0 |
| 置信度 | 除非某行另有说明,否则均为 CONFIRMED(byte-anchored) |
Viperfish(TPU v5)— 逐字段解码与 −20 Twin
目的
TensorCoreVectorExtended0Decoder::Decode(0x1ef6e4c0)和 …Extended1Decoder::Decode(0x1efb9760)从 Viperfish bundle 重建 TensorCoreVectorExtended0/1 proto。它们是 BitCopy 打包的 Viperfish MXU slot(Viperfish bundle)的逐字节精确逆过程;读取编码器写入的同一批 bit,独立确认每个位置。
入口点
TensorCoreVectorExtended0Decoder::Decode @0x1ef6e4c0 ── MXU0 (control region abs 48..64)
├─ TensorCoreVectorExtended0PredicationField::GetConcatenatedValue (read FIRST, bound < 0x10)
├─ …NoopOpcode::Matches
├─ …MatrixMultiply<fmt>Lgmr{Msra,Msrb}Opcode::Matches @0x1ef98580.. (mask 0xFE78…)
├─ …Pushmatrix<fmt>[Masked]Opcode::Matches @0x1ef98b80.. (mask 0xF878…)
└─ … (98 Extended0 op families)
TensorCoreVectorExtended1Decoder::Decode @0x1efb9760 ── MXU1 (control region abs 28..44, −20)
```text
### 算法 — Staged Copy 与字段访问器
```c
// TensorCoreVectorExtended0Decoder::Decode @ 0x1ef6e4c0 (decompiled, verified)
function Decode(span):
ve = arena.DefaultConstruct<TensorCoreVectorExtended0>()
*(qword*)stage = 1 // size-tag at offset 0
n = min(span.len, 9) // v10 = 9; if (a5 < 9) v10 = a5
memcpy(stage + 8, span.data, n) // bundle bytes at stage+8 (abs 0..)
pred = TensorCoreVectorExtended0PredicationField::GetConcatenatedValue(stage)
if (pred >= 0x10) return Error // 4-bit predicate bound on VF
ve.predication = pred
if (MatrixMultiplyBf16LgmrMsra::Matches(stage)) { decode matmul operands; return Ok }
…
if (PushmatrixBf16::Matches(stage)) { decode latch operands; return Ok }
…每个 operand 访问器都是在 offset 8(= abs bit 0)处 staged quadword 上的 shift & mask。两个访问器直接钉住 latch 控制字段:
// the two latch control fields (verified)
TensorCoreVectorExtended0PushmatrixBf16TransposeField::GetConcatenatedValue: // 0x1ef9db00
return (stage.qword[1] >> 57) & 1; // abs 57
TensorCoreVectorExtended0PushmatrixBf16TargetField::GetConcatenatedValue: // 0x1ef9db20
return (stage.qword[1] >> 58) & 1; // abs 58
```text
`stage.qword[1]` 是 offset 8 处的 staged quadword,所以 `>> 57` 读取绝对 bundle bit 57,`>> 58` 读取 abs 58 — 正是编码器的 `BitCopy(buf, 57, …, 1)` / `BitCopy(buf, 58, …, 1)` 写入的 bit(已在 `EncodeTensorCoreVectorExtended0PushmatrixBf16` @ `0x1efaf820` 中验证)。
### Latch Opcode/Mnemonic 解码表
latch(`Pushmatrix<fmt>`)的 `Opcode::Matches` 谓词用 mask `0xF878000000000000` 读取 staged quadword(bits 51..54 = data-format,bits 59..63 = opcode-high)。普通变体都携带 opcode-high 14;abs 51 处的 data-format 字段区分 dtype。masked 变体丢弃 format,并在不同的 opcode-high 值中携带 dtype(`>> 59 ==`):
| Mnemonic | opcode-high (abs 59 w5) | format (abs 51 w4) | Matches |
|---|---|---|---|
| `PushmatrixRounded` (`0x1ef98b80`) | 14 | 0 | `& 0xF878… == 0x7000000000000000` |
| `PushmatrixBf16` (`0x1ef98c00`) | 14 | 3 | `== 0x7018000000000000` |
| `PushmatrixBf8` (`0x1ef98c40`) | 14 | 4 | `== 0x7020000000000000` |
| `PushmatrixU8` (`0x1ef98c80`) | 14 | 5 | `== 0x7028000000000000` |
| `PushmatrixU8Masked` (`0x1ef98ca0`) | 20 | — | `>> 59 == 20` |
| `PushmatrixS4` / `…Masked` | 14 / 23 | 8 / — | per fmt |
完整的普通集合是在 format abs 51 处的 `{Rounded 0, PackedIf8Conv 2, Bf16 3, Bf8 4, U8 5, S8 6, U4 7, S4 8}`(opcode-high 始终为 14);masked 集合直接在 opcode-high abs 59 中携带 `{Rounded 15, PackedIf8Conv 17, Bf16 18, Bf8 19, U8 20, S8 21, U4 22, S4 23}`。没有 opcode-high 16 — `RoundedMasked` 是 15,然后 `PackedIf8ConvMasked` 是 17(format 1 没有 masked 变体)。
matmul(`MatrixMultiply<fmt>`)谓词使用 mask `0xFE78000000000000`(bits 51..54 format + bits 57..63 opcode);`MatrixMultiplyBf16LgmrMsra` 主体(`0x1ef98580`)是 `(stage.qword[1] & 0xFE78000000000000) == 0x0408000000000000`,解码为 abs 57 处的 opcode `0x2`(Msra)和 abs 51 处的 `MatmulDataFormat 1`(Bf16)。`MatmulDataFormat` enum(`Bf16 1, U8 2, S8 3, U4 4, S4 5, Bf8 6`)与 latch Pushmatrix format(Bf16 = 3)是一个**不同**的序号空间,虽然两者都占用 abs 51 w4。
> **QUIRK — opcode 字段在同一个 slot 中会随 op family 改变位置和宽度。** `MatrixMultiply<fmt>` 是 abs 57 处的 7-bit opcode;`Pushmatrix<fmt>` 是 abs 59 处的 5-bit opcode-high。在 latch/push 路径上,bits 57 和 58 被**重新用作** 1-bit `Transpose` 和 `Target` 字段 — 同样的物理 bit 在 matmul 路径上是 7-bit opcode 的两个高位。解码器通过 opcode-high 值来消歧(push/latch 14 对 matmul 的 `0x1`-family)。如果解码器把每个 op 都按 @57 的 7-bit opcode 来 mask,就会把 latch 的 Transpose/Target bit 读成 opcode bit。参见 [Viperfish bundle](bundle-vf-64b.md#mxu-slots--vectorextended0--vectorextended1)。
### −20 Twin
`Extended1Decoder::Decode` 是同样的扫描,只是控制区域低 20 bit。每个 MXU1 字段访问器都读取对应 MXU0 bit 减 20;八个 register-operand selector 在两个 slot 中读取**相同**的绝对 bit(共享 systolic-feed 池):
| Field | MXU0 abs | MXU1 abs | Δ |
|---|---|---|---|
| latch opcode-high | 59 | 39 | −20 |
| matmul opcode | 57 | 37 | −20 |
| data-format | 51 | 31 | −20 |
| Transpose | 57 | 37 | −20 |
| Target | 58 | 38 | −20 |
| predication | 64 | 44 | −20 |
| 8 register-operand selectors | 157/180/214/225/248/259/282/293 | (same) | 0 |
MXU1 访问器逐字节确认该偏移:`…Extended1PushmatrixBf16TransposeField`(`0x1efe8bc0`)读取 `>> 37 & 1`,`…TargetField`(`0x1efe8be0`)读取 `>> 38 & 1`;MXU1 matmul 谓词(`0x1efe3700`)mask `0xFE780000000`(opcode abs 37,format abs 31)。predication 字段也属于这个 twin:MXU0 predication 通过 `Extended0PredicationField` 读取(边界 `< 0x10`,abs 64),MXU1 通过 `Extended1PredicationField` 读取(abs 44)— 这是编码侧分析未能隔离出的 −20 细节,因为 predication 由单独的模板写入。
> **NOTE —** 解码侧同样确认存在两个 `VectorExtended` issue slot:二进制中有 98 个 `Extended0` 和 98 个 `Extended1` 的逐 op `Opcode::Matches` 解码 helper(`vxc::isa::TensorCoreVectorExtended{0,1}*Opcode::Matches`),并且没有 `Extended2`/`Extended3` 的 `Decoder::Decode`。物理 `mxu_count`(VF 上为 4)是由 unit_id quadrant 寻址的 systolic-array 数量,而不是额外的 bundle slot — 参见 [MXU Slot](slot-mxu.md#viperfish-v5p--named-opcode-families-and-the-latch-control-bits)。
---
## Transpose 与 Target Latch 字段 — 已解析
解码侧命名的两个 1-bit Viperfish latch 字段可以贯穿完整的 producer → encoder → decoder → cost-model 链。二者在编码侧分析中都只留下语义推断;解码器字段名加上 MLIR 生产者解析了它们。
### Transpose (abs 57)
`Transpose` 是 MLIR `tpu.matmul_push_rhs` op 的 `transpose` attribute — **在 latch 时把 RHS 权重矩阵转置后压入 systolic array**(matmul-with-transposed-weights at latch time)。链路如下:
```text
mlir::tpu::MatmulPushRhsOp attrs {mxu_index, staging_register, transpose}
└─ getStagingRegister @0x14b2e6a0
→ OpConversion → mlir::llo::VectorLatchIOp getMsr @0x13fbbea0, getMxuId @0x13fbbf00
→ ViperfishTensorCoreEmitter::EmitVectorLatchCommon
(sig …, MatpushTarget); Pushmatrix lambda @0x14204700:
stage[a2+0x20] = transpose_bool (proto +0x20) // [rsi+0x20] = dl
stage[a2+0x24] = MatpushTarget (proto +0x24) // [rsi+0x24] = ecx
→ EncodeTensorCoreVectorExtended0PushmatrixBf16 @0x1efaf820:
BitCopy(buf, 57, &proto[0x20], 0, 1) // Transpose @ abs 57
BitCopy(buf, 58, &proto[0x24], 0, 1) // Target @ abs 58
→ decoder TransposeField (>>57&1) / TargetField (>>58&1)producer lambda(0x14204700)把 bool transpose 参数写入 proto +0x20(*(_BYTE*)(a2+0x20) = a3),并把 MatpushTarget enum 写入 proto +0x24(*(_DWORD*)(a2+0x24)),这一点已由反编译确认。编码器随后把 +0x20 BitCopy 到 abs 57,把 +0x24 BitCopy 到 abs 58。解码器在 57/58 读回它们。因此 Transpose @ abs 57 控制 weight-transpose-at-latch,不同于独立的 EmitVectorTranspose op family(后者通过 XLU 路由数据)。
Target (abs 58)
Target 是 staging_register attribute = MatrixStagingRegister(MSR) bank 选择。每代的 *Target::MatrixStagingRegisterCount 说明了为什么该字段只从 Viperfish(TPU v5)开始存在:
| Generation | MatrixStagingRegisterCount | @ addr | Target field? |
|---|---|---|---|
| Jellyfish (TPU v2) | 1 | 0x1d490340 | 无(1 个 MSR,无需选择) |
| Pufferfish (TPU v4) | 1 | 0x1d4949e0 | 无 |
| Viperfish (TPU v5) | 2 | 0x1d49ace0 | abs 58(选择 MSR0 / MSR1) |
| Ghostlite (TPU v6e) | 2 | 0x1d497ae0 | (GXC 统一 opcode 方案,见下文) |
四者都是 xla::jellyfish::*Target::MatrixStagingRegisterCount。Viperfish 有两个 MSR bank,因此 abs 58 处的 1-bit Target 字段选择其中一个。JF/PF 只有一个 MSR,因此不携带 Target bit,这与 JF / PF slot map 中没有该字段一致。
GOTCHA — latch 的
transposebit 不是独立 transpose op。 Transpose @ abs 57 在权重矩阵被 push 进 array 时转置它(Pushmatrix-latch attribute)。另一个单独的EmitVectorTranspose<viperfish>(0x141c3f00)family 会发出TransposeStart/Continue/End/Packed/Segmentedopcode,经由 XLU/transpose unit 路由数据。它们是两种不同的 transpose 机制 — latch bit 是 latch 路径上对 matmul-opcode-LSB bit 的免费复用,不是 transpose-op opcode。重新实现者不能把它们合并。参见 MXU Slot。NOTE — 解码出的 Transpose / Target bit 会输入 cost model
SetReservations<MatpushModifier>(0x1c8abde0,构建flat_hash_map<MatpushModifier, array<int,19>>—MatpushModifierkey 编码{dtype × transpose},19-wide value 是逐MxuResource的 reservation vector;函数体检查resource_index < MxuResource::kNumMxuResources= 19,来自mxu_latency_table_vf.cc)以及 transpose-load latencyLatencyTableViperfish::XposeXLUReservationLatency(0x1c8a4f00)。精确的MatpushTargetordinal → 物理 MSR-bank 标签尚未隔离(value 0 = MSR0 / 1 = MSR1 是自然解读;对逐值 hardware-bank 映射的置信度为 LOW)。transpose字段的下游 systolic transpose-load 是被建模的 latency;该 bit 本身为 CONFIRMED。
GXC(Ghostlite v6e / 6acc60406 TPU7x)— 更宽 Opcode 与修正后的 Twins
GXC 世代保留 V5+ codec 形态 — staged copy、线性 Opcode::Matches — 但把 opcode 字段从 7 bit 扩到 8 bit,把 latch 判别器折叠进 opcode 低位,并改变 dtype 集合。
Ghostlite (v6e / glc)
glc 解码器(…Extended0Decoder::Decode @ 0x1f2f69a0)读取 abs 58 处的统一 8-bit opcode:matmul 使用完整 8-bit 值(0x2 Msra / 0x3 Msrb,MSR-select = opcode LSB),latch 的 opcode-high 位于 abs 60(w6),低两位 abs 58/59 充当 latch-class 判别器。dtype-class 是 abs 54 处的 2-bit 字段。
// glc PushMatrixBf16Opcode::Matches @ 0x1f326500 (verified)
v1 = stage.qword[1]; // abs 0..63
result = (~v1 & 0xC00000000000000) != 0 // bits 58,59 not both set (latch-class)
&& ((stage.oword >> 60) & 0x3F) == 0xE // opcode @ abs 60 w6 == 14 (float)
&& (v1 & 0xC0000000000000) == 0x80000000000000; // dtype-class @ abs 54 w2 == 2 (Bf16)
// glc MatrixMultiplyBf16LgmrMsraOpcode::Matches @ 0x1f325b60 (verified)
v1 = stage.oword;
return (((v1 >> 58) & 0xFF) == 2) // opcode @ abs 58 w8 == 0x2 (Msra)
&& ((v1 & 0xF0000000000000) == 0x10000000000000); // format @ abs 52 w4 == 1 (Bf16)
```text
abs 54 处的 dtype-class 字段携带由 opcode 选择的 4 元素 class 内部序号(14 = float,15 = int):float `{F32 0, If8 1, Bf16 2, Bf8 3}`,int `{U8 0, S8 1, U4 2, S4 3}`。`GhostliteTarget::MatrixStagingRegisterCount`(`0x1d497ae0`)返回 2。
MXU1 twin 是 **−21**,由 MXU1 谓词确认:`Extended1PushMatrixBf16Opcode`(`0x1f37ac60`)读取 opcode @ abs 39(mask `0x1F8000000000`,value `>> 39 = 14`)、dtype-class @ abs 33、guard @ abs 37/38;`Extended1MatrixMultiplyBf16LgmrMsra`(`0x1f37a5a0`)mask `0x1FE780000000`(opcode abs 37 = `0x2`,format abs 31)。每个字段相对 MXU0 都恰好 −21(op 60→39,class 54→33,matmul op 58→37,matmul fmt 52→31)。
| Field | MXU0 abs (glc) | MXU1 abs (glc) | Δ |
|---|---|---|---|
| latch opcode | 60 | 39 | −21 |
| dtype-class | 54 | 33 | −21 |
| matmul opcode (w8) | 58 | 37 | −21 |
| matmul format | 52 | 31 | −21 |
### `6acc60406`(cloud TPU7x / gfc)
`6acc60406` 系列是**仅 float**:它去掉 integer matmul group,支持四种 dtype `{F32, E4m3, Bf16, E5m2}` — 两个 FP8 format 被显式命名(相对于 Ghostlite 的 `If8`/`Bf8`)。gfc 解码器(`…Extended0Decoder::Decode` @ `0x1f96d020`)读取 abs 64(w6)处的 opcode-high、abs 59(w2)处的 dtype-class,以及 abs 62 处的单 bit latch valid-guard。
```c
// gfc PushMatrixBf16Opcode::Matches @ 0x1f98fd20 (verified)
result = ((stage.dword[4] & 0x3F) == 0xE) // opcode @ abs 64 w6 == 14 (all four float)
&& ((stage.qword[1] & 0x4000000000000000) == 0) // bit 62 clear (latch valid-guard)
&& ((stage.qword[1] & 0x1800000000000000) == 0x1000000000000000); // dtype-class @ abs 59 == 2 (Bf16)
// gfc MatrixMultiplyBf16LgmrMsraOpcode::Matches @ 0x1f98f740 (verified)
v1 = stage.oword;
return (((v1 >> 62) & 0xFF) == 2) // opcode @ abs 62 w8 == 0x2 (Msra)
&& ((v1 & 0x1E00000000000000) == 0x200000000000000); // format @ abs 57 w4 == 1 (Bf16)abs 59 处的 dtype-class 是 {F32 0, E4m3 1, Bf16 2, E5m2 3}。MXU1 twin 是 −25,由 Extended1PushMatrixBf16Opcode(0x1f9ccd60,opcode @ abs 39,value 14)和 Extended1MatrixMultiplyBf16LgmrMsra(0x1f9cc9a0,mask 0x1FEF00000000,opcode @ abs 37,format @ abs 32)确认:op 64→39,matmul op 62→37,format 57→32 — 全部恰好 −25。
| Field | MXU0 abs (gfc) | MXU1 abs (gfc) | Δ |
|---|---|---|---|
| latch opcode | 64 | 39 | −25 |
| dtype-class | 59 | 34 | −25 |
| matmul opcode (w8) | 62 | 37 | −25 |
| matmul format | 57 | 32 | −25 |
gfc twin 是 −25 而不是 Ghostlite 的 −21,因为 gfc 的 MXU0 锚点上移 +4(glc 60 → gfc 64),而 MXU1 锚点在两个 GXC 世代中都保持 abs 39:MXU0 的 +4 shift 叠加到了 MXU 间 delta 上。
NOTE — 跨世代分析在这里把 glc latch valid-guard 读作 abs 58/59 处的 2-bit 字段,但反编译的
glc PushMatrixBf16主体测试(~v1 & bits{58,59}) != 0(两者至少一个为 clear),并同时测试 abs 54 处的 dtype-class — 精确的 guard 极性和 gfc 1-bitbt 62等价宽度被视为 CONFIRMED 的单 bit/双 bit 测试,但其完整 latch-vs-matmul 边界语义属于 MXU Slot 页面的范围(对统一 opcode 边界值的置信度为 LOW)。上面的 opcode、dtype-class 和 matmul-format 位置全部为逐字节精确 CONFIRMED。
逐世代解码摘要
V5+ 解码参考(本页)补全了旧世代的 JF / PF 对应页:
| TpuVersion | Codename (binary) | Cloud | Decoder @ | MXU0 opcode | MXU1 opcode | Twin | dtype set |
|---|---|---|---|---|---|---|---|
| 3 | viperfish (vxc) | TPU v5 (v5e/v5p) | 0x1ef6e4c0 | matmul abs 57 / push abs 59 | abs 37 / 39 | −20 | 8 (int + float) |
| 4 | ghostlite (gxc::glc) | TPU v6e | 0x1f2f69a0 | unified abs 58 (w8) | abs 37 | −21 | 8 (int + float) |
| 5 | 6acc60406 (gxc::gfc) | TPU7x | 0x1f96d020 | unified abs 62 (w8) | abs 37 | −25 | 4 (float only) |
三者都使用 staged-copy + 线性 Opcode::Matches codec;逐世代差异是 opcode 变宽(7→8 bit)、dtype-set 改变(6acc60406 去掉整数并显式命名 FP8),以及 MXU 间 twin(−20 → −21 → −25)。编码侧(V5+ EmitX,Viperfish bundle)用 BitCopy(buf, abs_bit, …) 写入这些 bit,而解码的 Opcode::Matches mask 在相同 abs_bit 找回它们 — 三个世代的 round-trip 已闭合。