Skip to content

TEC Vector Opcode 枚举

本页中的每个 opcode 值、mask immediate、字段宽度和每代计数,都从 libtpu-0.0.40-cp314 wheel 中的 libtpu.so(build-id 89edbbe81c5b328a958fe628a9f2207d)逐字节读取。其他版本会不同。

摘要

TEC(Tile Execute Core)是 SparseCore 向量 datapath,而 VectorAlu 是其计算 slot:一个 64 字节 bundle 中有三条并发 lane(VectorAlu0/1/2),每条携带一个逐元素 / reduction / convert op。本页是 TEC Engine 页面的 opcode 名册配套页;TEC Engine 页面负责 64 字节 bundle、per-lane slot base(@438/401/364)和 37 位 slot 模板;这里枚举每个 VectorAlu 操作、其整数 opcode 值、其发射模板以及每代形态分裂。它是 SCS 标量 opcode 名册 的向量侧对应物,并从同类证据恢复:没有 opcode-name 字符串表,因此每个值都来自 per-op Matches() compare immediate,以及把 MCInst opcode → proto 字段 → emitter 模板映射起来的消费者 jump table。

该名册有两套独立恢复结果,不能混淆。第一套是 per-op match 谓词:libtpu 为每代每个 opcode 发射一个 C++ 类型 SparseCore<Slot><OpName>Opcode,每个类型都携带一个 Matches() const,它从解码后指令字中 mask 出 opcode 字段,并与该 op 的签名比较。三条 lane 的这些类型取并集得到 proto-enum op 计数:Viperfish 上 148 个,Ghostlite 上 229 个,6acc60406(gfc)上 257 个,该计数随代际增长。第二套是 SC-MLO emitter 的 ConsumeVectorAluInstruction 消费者:一个以 MCInst opcode 为 key 的 jump table,把每个 op 分派到 _internal_mutable_<op>() 和尾部 Emit* 模板。Ghostlite 消费者的表有 142 个不同 op(135 个单 op arm + 7 个经由一个共享 f32-compare/move oneof 链到达的 op);该表是重新实现者权威的 opcode→op→emitter 映射。142(jt arm)和 229(Matches-type union)以两种粒度统计同一 ISA:jt 把 per-predicate / per-lane-width / dtype-merged 形态折叠进 multi-opcode arm。

opcode 字段在 Ghostlite/6acc60406 上是 8 位(VectorAlu0 op @462),在 Viperfish 上是 7 位(@456。宽度增加承载了 148→229 的 op 增长,越过 7 位(128)上限;这也是 VF lane 为 36 位而 GF/GL 为 37 位的原因。opcode 空间本身是两级的:大多数值直接命名具体 op(VectorAddS32=3ByteNez=55),但少数是组逃逸0/1/2(unary EUP/convert)、27(pack)、90/128(vmask),其具体成员位于 6 位 sub-opcode 字段中;VectorSelect/VectorSelectNot 位于一个 4 位 select 子字段中,而 Viperfish 曾经使用 32 个显式 VectorSelectVmsk0..15 opcode。本页记录 opcode 恢复模型、per-lane slot opcode 字段宽度、带整数值的 GF direct 名册、unary/pack/vmask 组逃逸、八个发射模板、FP-vs-int 形态分裂以及每代 delta。

对重新实现而言,契约是:

  • opcode→op 映射是 ConsumeVectorAluInstruction jump table(Ghostlite,142 个 op)。 索引 opcode − 0xb26,边界 0x5cf;每个 arm 调用 _internal_mutable_<op>() 并 tail-jump 到一个 Emit* 模板。七个 f32 compare + VectorMove 共享一个 oneof-dispatch 链。6acc60406(gfc)的 per-op Matches() 谓词是 silicon-bit 交叉校验。
  • per-lane opcode 字段宽度和位位置。 GF/GL:8 位,VectorAlu0 @462VectorAlu1 @425VectorAlu2 @388(= slot_base + 24)。VF:7 位,lane 0 @456。opcode 不随 lane 变化(ByteNez=55 在三条 lane 上都一样);只有 bundle 位不同。
  • 八个发射模板。 EmitVectorBinop(约 92 个 op 的 arithmetic/compare/bitwise/shift 核心)、EmitVectorVxUnop(unary + 全部 unpack)、EmitExtendedVectorVxUnop(18 个 transcendental)、EmitVectorVyUnopEmitVectorModifyMask{Unop,Binop}(vmsk)、EmitVectorSelectEmitPackVectorBinopEmitCrossLaneUnopEmitVectorLaneLeftShiftInsert。模板决定 scheduler 必须满足的 operand-port 编码。
  • FP-vs-int 形态分裂和 VF→GF 重命名。 GF 按 dtype 命名每个 op(VectorAddS32 vs VectorAddBf16 vs VectorAddS16);VF 使用 dtype-merged generic 名称(VectorFloatAdd)以及 16 个显式 VectorSelectVmsk* opcode,GF 把它们折叠进 4 位子字段。GF 增加了 cosq/erf/sinq 和 VF 缺失的 FP8/Exmy small-float pack 家族。
SlotVectorAlu ×3 lanes(VectorAlu0 op @462VectorAlu1 @425VectorAlu2 @388,GF)
Opcode 宽度8 位(GF/GL)· 7 位(VF)
Opcode→mnemonic 来源per-op SparseCore<Slot><OpName>Opcode::Matches() immediate + ConsumeVectorAluInstruction jt
Matches-type union(每代)VF 148 · GL 229 · GF 257
Ghostlite 消费者 jt ops142(135 个单 op arm + 7 个共享 f32-cmp/move 链)
消费者入口ConsumeVectorAluInstruction<glc::SparseCoreTecBundle> 0x13a0b580;jt 0xae9d3dc,base 0xb26,bound 0x5cf
组逃逸unary 0/1/2(6 位 sub)· pack 27 · vmsk 90/128 · VectorSelect(4 位 sub)
发射模板EmitVectorBinop · …VxUnop · …ExtendedVxUnop · …VyUnop · …ModifyMask{U,B} · …Select · EmitPackVectorBinop · …CrossLaneUnop · …LaneLeftShiftInsert
代际不变性共享 op 值在 VF/GL/GF 中逐字节相同(ByteNez=55 在全部代上相同)
置信度已确认(反编译锚定),除非某行或 callout 另有说明

注意 — 本页枚举 VectorAlu opcode 名册;bundle 字节布局在 TEC Engine 中。 64 字节 bundle、三条 lane 的 slot base(@438/401/364)、37 位 slot 模板(四个 6 位 VREG selector、8 位 opcode @+24、重叠的 predication header @+32)以及 no-check-trailer 规则在那里记录,不在此重复。标量 slot 的 MCInst→slot 路由是 OneSlot Scalar RouterVectorAlu dispatch 是这里记录的单独 ConsumeVectorAluInstruction 消费者。VectorLoadVectorStoreVectorResultVectorExtended slot 在相邻页面有各自的 opcode 名册。


Opcode 恢复模型

为什么有两个 op 计数

VectorAlu ISA 可沿两条独立轴线恢复,重新实现者必须把它们分开。

第一条是 per-op match 谓词,形状与 SCS 标量谓词 相同。每个 opcode 是一个不同的空 C++ 类 SparseCoreTecVectorAlu<N><OpName>Opcode(每条 lane N ∈ {0,1,2}、每代各一个),携带一个 Matches() const,它从解码后指令字中 mask 出 opcode 字段并与该 op 的签名比较。签名就是 compare immediate;值就是 silicon opcode。统计三条 lane 上的不同 op 名称,得到 proto-enum op 计数:148(vfc)/ 229(glc)/ 257(gfc),由符号枚举确认。

第二条是 emitter 消费者 ConsumeVectorAluInstruction,SC-MLO code generator 调用该函数把 MCInst lowering 成 bundle 的 SparseCoreTecVectorAlu proto。它是一个基于 MCInst opcode 的 jump table:index = opcode − 0xb26,bound 0x5cf(Ghostlite 上 1488 个条目)。每个非 default arm 调用 SparseCoreTecVectorAlu::_internal_mutable_<op>() 来选择 proto oneof 字段,然后 tail-jump 到一个 Emit* 模板。统计 Ghostlite 表能到达的不同 op 得到 142(135 个单 op arm + 7 个经共享链到达)。jt 计数低于 Matches-type 计数,因为 jt 把 per-predicate / per-lane-width / dtype-merged MCInst 形态折叠进 multi-opcode arm。

text
two recoveries of one ISA
  Matches() types          ConsumeVectorAluInstruction jt
  (one per op, per lane)   (one arm per reachable op)
  vfc 148 / glc 229 /      glc 142 arms = 135 single-op
  gfc 257  (proto enum)      + 7 shared f32-cmp/move
        │                          │
        └── silicon opcode ────────┘  agree: ByteNez=55, VectorAddS32=3, …
            (the BitCopy value the encoder writes @462 = the cmp value Matches() reads back)
```text

> **怪癖 — 消费者 jump table 只存在于 Ghostlite;6acc60406(gfc)没有 `ConsumeVectorAluInstruction`。** `MCInst`→op jt-dispatch 消费者只存在于 `viperfish` 和 `ghostlite` namespace。gfc(6acc60406)emitter 在这个 wheel 中没有通过 `MakeTpuCoreProgram` 接线;只存在它的 `Matches()` 谓词类型和 `<Slot>Encoder::Encode` 主体。因此,**这里逐字节精确的 opcode→op 枚举是 Ghostlite 142-op 表**;**257-op gfc 名册是符号并集计数加上下文命名的 GF-only ops**(FP8/Exmy small-float 家族),它来自 `Matches()` 类型和 lane-0 encoder,而不是来自 jt。面向 gfc(6acc60406)的重新实现者使用 Ghostlite jt 作为结构模板,并加入 GF-only ops。

### Match 谓词:针对 slot word 的 form C

向量 slot 全部使用 mask-compare 谓词([标量分类](scalar-opcode-enum.md#form-c--mask-compare-the-alu-lanes)中的 form C):单个 AND-mask 从 slot word 中隔离 opcode 字段,然后结果与 `VAL` 比较;opcode 是 `VAL >> tzcnt(MASK)`。gfc lane-0 类型(`0x1ec09e00`)上的 `ByteNez`(op 55):

```c
// SparseCoreTecVectorAlu0ByteNezOpcode::Matches  (gfc 0x1ec09e00)
return (dword_0x40 & 0x3FC000) == 0xDC000;     // 0xDC000 >> 14 = 0x37 = 55 ; field bits 14..21 (8-bit)

Viperfish 上同一 op(0x1e94fd00)是低一位的 7 位字段:

c
// vxc::vfc …VectorAlu0ByteNezOpcode::Matches  (0x1e94fd00)
return (dword_0x40 & 0x7F00) == 0x3700;        // 0x3700 >> 8 = 0x37 = 55 ; field bits 8..14 (7-bit)
```text

而同一 op 在*另一条 lane*(gfc lane 1,`0x1ec4a6a0`)从不同字位置读取相同值:

```c
// gfc …VectorAlu1ByteNezOpcode::Matches  (0x1ec4a6a0)
return (qword_0x38 & 0x1FE0000000000) == 0x6E0000000000;   // 0x6E0…>>41 = 55 ; field bits 41..48

由此得出三个事实,它们是整个名册的脊柱:(a)opcode 不随 lane 变化:ByteNez=55 在全部三条 lane 和三代上都相同;(b)只有每条 lane 的位位置改变(lane 0 在 word 中较低,lane 1/2 较高),匹配 @462/@425/@388 bundle-bit 分裂;(c)字段宽度在 GF/GL 上是 8 位,在 VF 上是 7 位。

怪癖 — encoder 的 switch case label 是 proto-oneof tag,不是 opcode 值。 在 gfc VectorAlu0Encoder::Encode0x1ec11100)中,dispatch switch(*(msg+88)) 使用顺序 proto-oneof case label:case 8 → BitCopy(.,462,.,8) = 3VectorAddS32),case 9 → 87VectorAddS16),case 10 → 4VectorSubtractS32),case 11 → 88VectorSubtractS16)。case number 是 oneof 字段 tag;写入 bundle opcode 字段 bit 462 的值才是 silicon opcode。把 switch case number 当成 opcode 的重新实现者会把每个 op 都编码错。本页的值是 BitCopy/Matches() 硬件值,与标量页面完全一致。

Slot opcode 字段位位置

已对照 gfc VectorAlu0Encoder::Encode0x1ec11100)逐字节确认,其 BitCopy 调用会把四个 6 位 VREG selector、8 位 opcode 和 predication header 写入固定的绝对 bundle 位。三条 lane 共享一个模板(见 TEC Engine);只有 slot base 平移。

LaneSlot base(GF)VREG selectorsOpcode bitOpcode widthPred header
VectorAlu0438438 / 444 / 450 / 4564628470 / 473 / 474
VectorAlu1401401 / 407 / 413 / 4194258433 / 436 / 437
VectorAlu2364364 / 370 / 376 / 3823888396 / 399 / 400
VectorAlu0(VF)432432 / 438 / 444 / 4504567463 / 467

opcode 总是落在 slot_base + 24。Viperfish lane 窄 1 位(7 位 opcode → 36 位 slot),所以其 lane-0 opcode 位于 @456 而不是 @462;VF predication header 是单通道 4 位形态,而不是 GF 的 3+4 重叠形态(见 TEC Engine)。


Ghostlite VectorAlu 消费者 Jump Table

Dispatch 形状

ConsumeVectorAluInstruction<glc::SparseCoreTecBundle>0x13a0b580)是权威的 opcode→op→emitter 映射。它读取 MCInst opcode,以 opcode − 0xb26 索引 0xae9d3dc 处的 jump table(bound 0x5cf = 1488 个条目),并分派到 143 个 target 之一:142 个 op arm + 一个 default-error arm,覆盖 1213 个 opcode。

c
function ConsumeVectorAluInstruction(printer, mcinst, vregports, ...):   // glc 0x13a0b580
    opcode = mcinst.opcode                       // DWORD[mcinst]
    idx = opcode - 0xb26                          // jt base 0xb26
    if (unsigned)idx > 0x5cf:                      // bound check
        return MakeError("Unsupported opcode for Vector Alu slot: $0 : $1")  // isa_emitter.cc
    switch (jt[idx]):                              // jt @0xae9d3dc, 1488×int32 rel offsets
        // 135 single-op arms, e.g.:
        case 0xb26:  proto.mutable_vector_add_bf16();  return EmitVectorBinop<…VectorAddBf16>(mcinst)
        case 0xc9f:  proto.mutable_cosq_f32();          return EmitExtendedVectorVxUnop<…CosqF32>(mcinst)
        case 0xf2e:  proto.mutable_tanh_f32();          return EmitExtendedVectorVxUnop<…TanhF32>(mcinst)
        case 0xe87:  GetOperandAndVsEncoding(…);
                     proto.mutable_pack_compressed_b16_to_b8();
                     return EmitPackVectorBinop<…PackCompressedB16ToB8>(mcinst)
        // 7 ops via ONE shared f32-cmp/move chain, selected by the proto oneof tag [proto+0x50]:
        case 0xcd2: case 0xd56: … : goto shared_cmp_move   // 0x28→EqF32 … 0x2d→LteF32 ; 0x1a→VectorMove
        default:    return MakeError(…)            // 1213 opcodes
```text

名册下方 opcode 列中的 "`..`" 标记 multi-opcode arm:同一个 proto op 和 `Emit*` 模板可从 23 个相邻 `MCInst` opcode 到达(predicated / non-predicated / lane-width 形态)。opcode→op 映射逐字节精确;multi-opcode arm 内的 per-opcode operand-form decode 不是逐字节精确(由 `GetOperandAndVsEncoding` / `GetVregno` 填充,未追踪)。

### 142-op 计数

| 家族 | 计数 | 说明 |
|---|---:|---|
| Integer/float 核心 VALU | ~92 | add/sub/mul/min/max/compare/bitwise/shift/clamp/relux/classify/select/convert/carry/total/broadcast/permute/popcount/clz/lane_id/byte_nez/create_mask/inf_or_nan + vmsk ALU + mask scan/reduce;**包含 7 个 f32-cmp/move 共享链 op** |
| Transcendental | 18 | 9 个家族 × {f32, bf16}: `cosq` `erf` `log_two` `pow_two` `reciprocal` `reciprocal_sqrt` `shifted_sigmoid` `sinq` `tanh` |
| Quant pack/unpack | 32 | 6 个 `pack_*` + 24 个 `unpack_*` + 2 个 `vmsk_pack_{even,low}` |
| **总计** | **142** | 135 个单 op jt arm + 7 个共享链 op |

该计数经字节确认:消费者主体正好引用 **135 个不同 `_internal_mutable_<op>()` accessor**(单 op arm),再加七个通过 oneof 链到达的 f32-compare/move op。同一主体中的 `Emit*` 模板分布为:**66 个 `EmitVectorBinop` · 34 个 `EmitVectorVxUnop` · 18 个 `EmitExtendedVectorVxUnop` · 6 个 `EmitPackVectorBinop` · 7 个 `EmitVectorModifyMask{U,B}` · 4 个 `EmitCrossLaneUnop` · 3 个 `EmitVectorVyUnop` · 2 个 `EmitVectorSelect` · 1 个 `EmitVectorLaneLeftShiftInsert`**,其中 18 个 `EmitExtendedVectorVxUnop` 正好就是 18 个 transcendental。

> **易错点 — 七个 f32 compare 和 `VectorMove` 不是七个不同 jt arm;它们共享一个 oneof-dispatch 链。** opcode `{0xcd2,0xcd6,0xcda,0xd56,…}` 和 `VectorMove` opcode 都落在一个 handler 上,该 handler 切换 `[proto+0x50]` 处的 proto oneof discriminator:`0x28→VectorEqF32`、`0x29→VectorNeqF32`、`0x2a→VectorGtF32`、`0x2b→VectorGteF32`、`0x2c→VectorLtF32`、`0x2d→VectorLteF32`(全部 `EmitVectorBinop`)、`0x1a→VectorMove`(`EmitVectorVyUnop`)。统计 jt arm 得到 135;统计可达 op 得到 142。这 7 个是真实 op,具有真实 opcode 值;它们只是没有私有 arm。

---

## GF Direct Opcode 名册

### Arithmetic、compare、bitwise、shift 核心(`EmitVectorBinop`)

ISA 主体是 direct binary op,其 opcode 就是字段值。integer/bitwise op 的值代际不变(`VectorBitwiseAnd=6`、`ByteNez=55` 在 VF/GF 中逐字节相同)。dtype 后缀是 opcode 的一部分,不是操作数:`VectorAddS32`、`VectorAddS16`、`VectorAddBf16`、`VectorAddF32` 是四个不同 opcode。

| Opcode | Mnemonic | Opcode | Mnemonic |
|---:|---|---:|---|
| 3 | `VectorAddS32` | 32 | `VectorMultiplyBf16` |
| 4 | `VectorSubtractS32` | 33 | `VectorMaxBf16` |
| 5 | `VectorMultiplyU32` | 34 | `VectorMinBf16` |
| 6 | `VectorBitwiseAnd` | 44 | `VectorCarryU32` |
| 7 | `VectorBitwiseOr` | 45 | `VectorBitwiseAndn` |
| 8 | `VectorBitwiseXor` | 55 | `ByteNez` |
| 9 | `VectorLogicalShiftLeft` | 84 | `VectorMaxU32` |
| 10 | `VectorLogicalShiftRight` | 85 | `VectorMinU32` |
| 11 | `VectorArithmeticShiftRight` | 86 | `VectorMultiplyReturningHighHalfU32` |
| 14 | `VectorMultiplyF32` | 87 | `VectorAddS16` |
| 15 | `VectorMaxF32` | 88 | `VectorSubtractS16` |
| 16 | `VectorMinF32` | 89 | `VectorMultiplyU16` |
| 17 | `VectorReluxF32` | 56 | `VectorMaxU16` |
| 18 | `VectorClampF32` | 57 | `VectorMinU16` |
| 22 | `VectorMove` | 75 | `VectorCarryU16` |

`VectorAddS32=3`、`VectorAddS16=87`、`VectorSubtractS32=4`、`VectorSubtractS16=88` 已对照 gfc lane-0 encoder 确认,其 proto-oneof switch 在 bit 462 写入这些精确值。`ByteNez=55` 已对照三条 lane 和三代上的 `Matches()` immediate 确认。

### Compare block(per-dtype,密集)

compare 按 dtype 布局成 `{Eq, Neq, Gt, Gte, Lt, Lte}` 的密集区间。S32/S16/U32/U16/Bf16 block 是 direct opcode;**F32 block 是共享 oneof 链**(opcode `0x28..0x2d`),不是 direct value。

| Block | Opcodes | Ops |
|---|---|---|
| S16 compare | 65 / 66 / 67 / 68 / 69 / 70 | `Eq Neq Gt Gte Lt Lte S16` |
| S32 compare | 38 / 39 / 40 / 41 / 42 / 43 | `Eq Neq Gt Gte Lt Lte S32` |
| U32 compare | 80 / 81 / 82 / 83 | `Gt Gte Lt Lte U32` |
| U16 compare | 71 / 72 / 73 / 74 | `Gt Gte Lt Lte U16` |
| Bf16 compare | 76 / 77 / 78 / 79 | `Eq Neq Gt Gte … Bf16` |
| F32 compare | `0x28..0x2d`(oneof) | `Eq Neq Gt Gte Lt Lte F32` |
| F32 total | 53 / 54 | `VectorTotalLtF32` / `VectorTotalLteF32` |
| Bf16 total | 26 / 36 | `VectorTotalLtBf16` / `VectorTotalLteBf16` |

### Cross-lane、mask 和 broadcast/permute

高 opcode 区域是 cross-lane 和 mask 组:broadcast、rotate、permute、lane-shift-insert 和 vmsk ALU。若干使用 `EmitCrossLaneUnop` 或 `EmitVectorModifyMask*`,而不是 `EmitVectorBinop`。

| Opcode | Mnemonic | Template |
|---:|---|---|
| 52 | `CreateMask` | `EmitVectorVyUnop` |
| 91 / 92 / 93 | `VmskAnd` / `VmskOr` / `VmskXor` | `EmitVectorModifyMaskBinop` |
| 94 | `VmskPackLow` | `EmitVectorModifyMaskBinop` |
| 138 | `VmskPackEven` | `EmitVectorModifyMaskBinop` |
| 129 / 130 | `VectorBroadcastB32` / `…B16` | `EmitVectorBinop` |
| 131 / 132 | `VectorRotateB32` / `…B16` | `EmitVectorBinop` |
| 133 / 134 / 135 | `VectorPermuteB32` / `…B16` / `…B8` | `EmitVectorBinop` |
| 136 / 137 | `VectorLaneLeftShiftInsertB32` / `…B16` | `EmitVectorLaneLeftShiftInsert` |
| 139 / 140 / 141 | `VectorMaskPermuteB32` / `…B16` / `…B8` | `EmitCrossLaneUnop` |

> **注意 — 高 opcode(129..151)是 GF/GL-only,且其中若干是 gfc-only。** 129..141 的 broadcast/rotate/permute/lane-shift block 和 142..151 的 FP8/Exmy pack 家族是 8 位值(> 127),无法存在于 7 位 Viperfish 空间。它们属于 257-op gfc(6acc60406)并集,但 FP8 家族高于 Ghostlite jt 的可达 arm;Ghostlite jt 可到达 `vector_permute_b32`(`0x10e8`)、`vector_broadcast_b32`(`0x107b`)以及 mask-permute / cross-lane ops,但 FP8 `PackCompressed*ToExmy` ops 是 gfc-only(见 [每代 Delta](#每代-delta))。

---

## 组逃逸和 Sub-Opcodes

少数 primary opcode 不命名具体 op,而是命名一个**,并由 6 位 sub-opcode 字段(struct-word `0x40` bit 2)选择成员。这就是 EUP transcendental 和完整 pack/unpack 矩阵适配有限 primary-opcode 空间的方式。escape primary 是 `0`(unary float)、`1`(unpack-to-32)、`2`(unpack-to-16 / round)、`27`(pack)、`90`(vmsk move)、`128`(vmsk-count / E-format unpack);`VectorSelect`/`VectorSelectNot` 使用 bit 18 处的单独 4 位 select 子字段。

| Primary | Group | Sub field | 代表成员(sub value) |
|---:|---|---|---|
| 0 | unary float / convert | 6 位 `@bit2` | `VectorPopulationCount(1)`, `VectorCountLeadingZeros(2)`, `VectorCeilingF32(3)`, `VectorFloorF32(4)`, `VectorConvertS32ToF32(5)`, `VectorConvertF32ToS32(6)`, `ErfF32(14)`, `LogTwoF32(18)`, `TanhF32(19)`, `ReciprocalF32(21)`, `SinqF32(23)`, `CosqF32(24)` |
| 1 | unpack-to-32 | 6 位 `@bit2` | `Unpack{Compressed,Interleaved}{Bf16,Hf16,S16,E5m2,S8,…}…ToF32/ToS32`(32 个 sub-op) |
| 2 | unpack-to-16 / round | 6 位 `@bit2` | `UnpackCompressed{S8,U8}…To{Bf16,S16,U16}`, `VectorRoundToIntegral{Even,Away}{F32,Bf16}`(32 个 sub-op) |
| 27 | pack | 6 位 `@bit2` | `Pack{Interleaved,Compressed}{F32→Bf16,B32→B16,B16→B8,…}`, `VectorTruncateFractional{F32,Bf16}`(32 个 sub-op) |
| 90 | vmsk move | 6 位 `@bit2` | `VmskMove(0)`, `VmskNegate(1)` |
| 128 | vmsk-count / E-unpack | 6 位 `@bit2` | `VectorMaskPopulationCountB32(0)/B16(1)`, `VectorMaskPrefixSumB32(2)/B16(3)`, `VectorMaskCountTrailingZerosB32(4)/B16(5)`, `UnpackCompressed{E5m2,E4m3}…ToBf16` |
|| select | 4 位 `@bit18` | `VectorSelect(6)`, `VectorSelectNot(7)` |

> **注意 — Ghostlite jt 直接到达组成员,因此本页也在 flat opcode 下列出它们。** 上面的 escape 模型是*编码*(silicon opcode 字段如何存储 group + sub-opcode);Ghostlite 消费者 jt 索引完整 `MCInst` opcode 空间,并通过各成员自己的 arm 到达每个成员(`cosq_f32 @0xc9f`、`pack_compressed_b16_to_b8 @0xe87`、24 个 `unpack_compressed_*` arm)。编码到 silicon 的重新实现者写入 group primary + 6 位 sub;基于 `MCInst` jt 驱动的实现使用 per-member arm。这两种视图是同一 op 集;sub-opcode `@bit2` 是桥梁。
>
> **易错点 — `VectorSelect`/`VectorSelectNot` 是带 4 位子字段的一个 opcode;在 Viperfish 上它们是 32 个显式 opcode。** GF 把 predicate-mask select 编码为 `VectorSelect`/`VectorSelectNot` 加上 struct bit 18 处的 4 位 select 子字段(16 个 mask source)。Viperfish 改为拥有 16 个显式 `VectorSelectVmsk0..15`(opcode 96..111+ 16 个 `VectorSelectNotVmsk0..15`(opcode 112..127),覆盖完整 96..127 区间。把这 32 个 opcode 折叠进 4 位子字段,节省了空间来在 8 位空间内支持 GF transcendental 和 pack-family 扩展。重新实现者不得在 GF/GL 上发射 32 个不同 select opcode,也不得在 VF 上发射 4 位 select 子字段。

---

## 八个发射模板

消费者把每个 op 路由到八个 `Emit*` 模板之一。模板不是表面装饰;它固定该 op 消费哪些读端口(Vx / Vy),因此也固定 bundle scheduler 必须在三条 lane 间满足的 `SparsecoreVregReadPort` 冲突(见 [TEC Engine](tec-engine.md#immediate-slot-indexing))。

| Template | 服务的 ops | 计数(glc) |
|---|---|---:|
| `EmitVectorBinop<…VregReadPort>` | arithmetic/compare/bitwise/shift/clamp/relux/classify/carry/total/broadcast/permute 核心 | 66 |
| `EmitVectorVxUnop` | ceiling/floor/convert/popcount/clz/lane_id/inf_or_nan + **全部 `unpack_*`** | 34 |
| `EmitExtendedVectorVxUnop` | **18 个 transcendental**(`cosq`/`erf`/`log_two`/`pow_two`/`reciprocal`/`reciprocal_sqrt`/`shifted_sigmoid`/`sinq`/`tanh` × {f32,bf16}) | 18 |
| `EmitVectorVyUnop` | `byte_nez`、`create_mask`、`VectorMove`(Vy 读端口) | 3 |
| `EmitVectorModifyMask{Unop,Binop}` | `vmsk_*` ALU(`and/or/xor/negate/move/pack_even/pack_low`) | 7 |
| `EmitVectorSelect` | `vector_select`、`vector_select_not` | 2 |
| `EmitPackVectorBinop` | 6 个 `pack_*` ops(每个先调用 `GetOperandAndVsEncoding`) | 6 |
| `EmitCrossLaneUnop` | `vector_mask_{count_trailing_zeros,population_count_b16/b32,prefix_sum}_b32` | 4 |
| `EmitVectorLaneLeftShiftInsert` | `vector_lane_left_shift_insert_b32` | 1 |

> **注意 — `EmitExtendedVectorVxUnop` 是 transcendental 路径,并通过 EUP pipeline 路由。** 该模板服务的 18 个 op 是 SC 的非线性激活引擎:它们使用 Vx 读端口,在 extended(EUP)pipeline 上运行,结果通过 [VectorResult](tec-engine.md) slot 排出,方式与 [VectorExtended](vectorextended-vex.md) scan 相同。重新实现者必须把这些建模为不同于单周期 `EmitVectorBinop` arithmetic 的多周期 EUP op;per-op operand→function→result 绑定是剩余最大的缺口(unary-group sub-opcode `@bit2` 选择函数,但其消费的 VREG selector 未追踪)。

---

## 相邻 Vector Slot(op 计数)

`VectorAlu` 是五个 vector slot 之一;另外四个在相邻页面有各自的 opcode 名册。这里为完整性而总结;整数值位于链接页面。

| Slot | Opcodes(GF) | 名册形状 | 页面 |
|---|---:|---|---|
| `VectorAlu` ×3 | **257**(GF union/ 142(GL jt) | 本页 ||
| `VectorLoad` | 5 | `TileSpmemLoad{,CircularBuffer,CircularBufferPostUpdate,Indexed,IndexedCircularBuffer}`(3 位字段) | [VectorLoad Slot](vectorload-slot.md) |
| `VectorStore` | 33 | `TileSpmemStore` base + 32 个 typed `Add`/`CircularBuffer`/`Indexed` scatter 变体(6 位字段) | [VectorStore Slot](vectorstore-slot.md) |
| `VectorResult` | 8 | `EupResult`, `PopXrfWriteAll`, `PopXrfWritePartial0..4`, `VresMove`(3 位字段) | [TEC Engine](tec-engine.md) |
| `VectorExtended` | 53 | `AddScan*`/`MinScan*`/`MaxScan*`/`*IndexScan*`/`Segmented*`/`Sort*`/`Uniquify*`/`DuplicateCount*`(6 位字段) | [VectorExtended (VEX)](vectorextended-vex.md) |

> **易错点 — `VectorStoreAdd*` 是 atomic scatter-add,编码在 opcode 中,不是操作数。** 如 [VectorStore](vectorstore-slot.md) 页面所述,per-dtype `…StoreAdd{S32,F32,S16,Bf16}` 变体累加到 `TILE_SPMEM`,即 embedding-gradient 写路径,并且 dtype 是 opcode 的一部分。同样的 dtype-as-opcode 规则也支配 `VectorAlu`:不存在 element-type 操作数字段;`VectorAddS32`/`VectorAddBf16`/`VectorAddS16`/`VectorAddF32` 是四个 opcode。

---

## 每代 Delta

`VectorAlu` ISA 按 VF→GL→GF 增长,增长集中在三处:opcode 字段宽度、transcendental 集合、dtype/select 形态分裂。共享 op 值代际不变(`ByteNez=55`、`VectorAddS32=3` 跨代逐字节相同);delta 是*新增* op 和*重命名*形态。

| Aspect | Viperfish(vfc) | Ghostlite(glc) | 6acc60406(gfc) |
|---|---|---|---|
| Opcode field width / lane-0 bit | 7-bit / `@456` | 8-bit / `@462` | 8-bit / `@462` |
| `Matches`-type union3 lanes) | **148** | **229** | **257** |
| Consumer ops(distinct accessors) | 86 | **142**135 single + 7 shared) | (此 wheel 中无 consumer) |
| Max primary opcode | 127(`VectorSelectNotVmsk15`,完整 7 位) | ~250 | 151 |
| Transcendental families | 6(dtype-merged: `tanh`, `reciprocal`, `reciprocal_sqrt`, `log_two`, `pow_two`, `shifted_sigmoid`) | 9 × {f32,bf16} = 18 | 18 + |
| `cosq` / `erf` / `sinq` | **absent**(主体中 0 refs) | **present**6 ops) | present |
| Op naming | dtype-merged generic(`VectorFloatAdd`, `tanh`) | dtype-suffixed split(`VectorAddF32`, `tanh_f32`) | dtype-suffixed split |
| Select forms | 32 个显式 `VectorSelect[Not]Vmsk0..15`(op 96..127| 折叠进 4 位 select 子字段 | 4 位 select 子字段 |
| FP8 / Exmy small-float | absent | partial(pack/unpack matrix) | **`VectorConvertStochasticF32ToE5m2`, `PackCompressedF32ToExmy`, `VectorConvertExmyToE4m3`, `UnpackCompressedExmyLanes07ToBf16`**(GF-only) |
| Inline-immediate path | oneof tag `0x13` → `SparseCoreImmediates`(2 个 shared arm) | 折叠进 cmp/move/total datapath | (n/a) |

存在性声明由每代 namespace 中对应 type / accessor 的存在确认。Viperfish 消费者主体(`0x1399ffe0`)对 `cosq`/`erf`/`sinq` **零引用**,但引用 `tanh`(dtype-merged 单 op);这 +3 个 transcendental 家族是 Ghostlite 新增。Viperfish 有 4 个 `SparseCoreImmediates` 引用和 2 个 `GetVectorYAndEmitImmediate` 引用:其 oneof-tag-`0x13` 形态通过 `GetVectorYAndEmitImmediate` 路由 inline vector immediate,而 Ghostlite 把该路径折叠进 compare/move/total 链。

> **注意 — VF→GL 的 pack/unpack delta 是分裂,不是新增。** Viperfish 已经有自己的 27-op pack/unpack 家族,使用较旧的 sublane-indexed 命名(`pack_bf16_compressed`、`unpack_bf8_sublanes_0_1`、`unpack_lower_bf16_interleaved`)和 6 个 dtype-merged transcendental。真正的 Ghostlite delta 是:(a)三个** transcendental 家族 `cosq`/`erf`/`sinq`(VF 上不存在);(b)每个 merged op 的 per-dtype / per-lane-range *分裂*(每个 VF `tanh` → GL `tanh_f32` + `tanh_bf16`;每个 `unpack_bf8_sublanes_*` → `unpack_compressed_bf8_lanes_*_to_f32`),这推动了大部分 arm 增长(Ghostlite 到达 142 个 op,而 VF 消费者有 86 个不同 accessor);(c)把 VF inline-immediate 路径折叠进 datapath。gfc(6acc60406257-op 并集在此之上增加 FP8/Exmy small-float 家族。

---

## 函数映射

除非另有说明,所有地址均为 gfc(6acc60406);`Matches()` immediate 和 `BitCopy` 值是权威 opcode 值。

| Symbol | Address | Opcode evidence |
|---|---|---|
| `ConsumeVectorAluInstruction<glc::SparseCoreTecBundle>` | `0x13a0b580` | opcode→op jt(base `0xb26`,bound `0x5cf`);135 个单 op arm + 7 个 shared |
| `ConsumeVectorAluInstruction<viperfish>` | `0x1399ffe0` | VF consumer(86 个不同 `_internal_mutable_*` accessor;无 cosq/erf/sinq;`SparseCoreImmediates` path) |
| `VectorAlu` jt(glc) | `0xae9d3dc` | 1488×int32 rel offsets;143 个 target(142 个 op + default) |
| `SparseCoreTecVectorAlu0ByteNezOpcode::Matches`(gfc) | `0x1ec09e00` | `(dword[+0x40] & 0x3FC000) == 0xDC000` → 558 位 `@bit14` |
| `SparseCoreTecVectorAlu0ByteNezOpcode::Matches`(vfc) | `0x1e94fd00` | `(dword[+0x40] & 0x7F00) == 0x3700` → 557 位 `@bit8` |
| `SparseCoreTecVectorAlu1ByteNezOpcode::Matches`(gfc) | `0x1ec4a6a0` | `(qword[+0x38] & 0x1FE0…) == 0x6E0…` → 55,`@bit41`(lane 1|
| `SparseCoreTecVectorAlu0Encoder::Encode`(gfc) | `0x1ec11100` | opcode `BitCopy(.,462,.,8)`;sel `@438/444/450/456`;pred `@470/473/474`;case8→3,case9→87,case10→4,case11→88 |
| `SparseCoreTecVectorAlu0Encoder::Encode`(vfc) | `0x1e954ae0` | opcode `BitCopy(.,456,.,7)`(7 位 VF 形态) |
| `EmitExtendedVectorVxUnop<…CosqF32>`(glc) | `0x13a1d800` | transcendental 发射模板;从 `case 0xc9f` tail-jump |
| `EmitVectorBinop<…VectorAddBf16>`(glc) | `0x13a1b000` | arithmetic-core 模板;从 `case 0xb26` tail-jump |
| `EmitPackVectorBinop<…PackCompressedB16ToB8>`(glc) | `0x13a1ff20` | pack 模板;前置 `GetOperandAndVsEncoding` |
| `BitCopy` | `0x1fa0a900` | LE packer `(dst, dst_bitoff, src, src_bitoff, nbits)` |

跨代锚点:per-op `Matches()` 类型存在于全部三个 `isa` namespace(`vxc::vfc`、`gxc::glc`、`gxc::gfc`);三条 lane 的名称并集按符号枚举为 **148 / 229 / 257**。Ghostlite 消费者错误字符串是 "`Unsupported opcode for Vector Alu slot: $0 : $1`"(`isa_emitter.cc`,一个 `absl::Substitute` 模板)。精确匹配 `SparseCoreTecVectorAlu[012]` 前缀,以免把标量(`SparseCoreScalar*`)或 TensorCore(`TensorCore*`)谓词类型拉入 vector 名册。

---

## 注意事项

- **142(jt arms)≠ 229(Matches-type union);二者都是真实的,只是粒度不同。** Ghostlite jt 到达 142 个 op,因为它把 dtype-merged / per-lane-width / predicated `MCInst` 形态折叠进 multi-opcode arm 和 7-op 共享链。229(glc)/ 257(gfc)数字统计三条 lane 上不同的 `Matches()` op 类型。构建 assembler 的重新实现者使用 jt;构建 disassembler/validator 的实现者使用 `Matches()` 谓词。
- **opcode 值不随 lane 变化;bundle 位会变化。** `VectorAlu0/1/2` 从 `@462/425/388` 解码相同 opcode 值。三条 lane 并发 issue,因此 scheduler 必须遵守每个 bundle 的 `SparsecoreVregReadPort` 冲突(所选 `Emit*` 模板要求的读端口),这点未完整追踪;六个 [immediate slot](tec-engine.md#immediate-slot-indexing) 限制不同 `VectorY` literal 的数量。
- **dtype 位于 opcode 中,从不是操作数。** `VectorAdd{S32,S16,Bf16,F32}` 和 `tanh_{f32,bf16}` 是不同 opcode。如果重新实现者编码单个 `VectorAdd` 加 dtype 操作数,会在 GF/GL 上误编码;dtype-merged 形态只存在于 Viperfish,其中元素类型位于操作数/格式字段中(推断,未解码操作数)。
- **6acc60406(gfc)在此 wheel 中没有 jt(arm 级事实为低置信度)。** gfc opcode→op 枚举是符号并集计数加 lane-0 encoder 和 `Matches()` 谓词;per-`MCInst`-opcode arm 映射是 Ghostlite jt。GF-only FP8/Exmy ops(`PackCompressedF32ToExmy`、`VectorConvertStochasticF32ToE5m2`、`VectorConvertExmyToE4m3`、`UnpackCompressedExmyLanes07ToBf16`)已确认为 `Matches()` 类型,但其精确 `MCInst` opcode 没有 jt 锚定。
- **Sub-opcode 操作数绑定是剩余缺口(高/低)。** 组逃逸(`0/1/2/27/90/128`)及其 6 位子字段 `@bit2` 已结构性恢复;per-sub-op VREG-selector→function→XRF-result 绑定(每个 transcendental 和 unpack 消费哪个 Vx/Vy 端口、结果落在哪里)未追踪。按 primary opcode + 子字段解码;operand-to-port 映射仍未解决。

---

## 相关组件

| Name | Relationship |
|---|---|
| `ConsumeVectorAluInstruction`(`0x13a0b580` glc) | 本页枚举的 opcode→op→`Emit*` jt |
| `SparseCoreTecVectorAlu0Encoder::Encode`(`0x1ec11100` gfc) | 写入 8 位 opcode `@462` 和 VREG selector;`BitCopy`-immediate 来源 |
| per-op `SparseCoreTecVectorAlu<N><Op>Opcode::Matches()` | opcode→mnemonic 来源:每个 op、每条 lane、每代一个类型(148/229/257 union|
| `EmitExtendedVectorVxUnop<>`(`0x13a1d800` glc) | transcendental 发射模板(18-op EUP 路径) |
| `BitCopy`(`0x1fa0a900`) | 每个 slot encoder 用来写 opcode 位的 LE packer |

## 交叉引用

- [TEC(Vector)Engine](tec-engine.md) — 64 字节 bundle、三个 `VectorAlu` lane slot base(`@438/401/364`),以及本名册 opcode 字段所在的 37 位 slot 模板。
- [SCS 标量 Opcode 枚举](scalar-opcode-enum.md) — 标量侧 opcode 名册;相同的 `Matches()`-predicate / encode-switch-vs-silicon-value 模型。
- [OneSlot Scalar Router](oneslot-router.md) — 路由*标量* slot 的 `ConsumeOneSlotInstruction` jt;`VectorAlu` dispatch 是这里记录的单独消费者。
- [VectorExtended(VEX)](vectorextended-vex.md) — scan/sort/uniquify slot(53 ops);transcendental `EmitExtendedVectorVxUnop` ops 共享其 EUP pipeline。
- [VectorLoad Slot](vectorload-slot.md) — 5-op tile vector-load 名册。
- [VectorStore Slot](vectorstore-slot.md) — 33-op tile vector-store + scatter-add 名册。
- [SparseCore 概览](overview.md) — 三类 engine、每代存在性以及 `TpuSequencerType` codec-template enum
- **二进制:** `extracted/libtpu-0.0.40-cp314-cp314-manylinux_2_31_x86_64/libtpu/libtpu.so`(build-id `89edbbe81c5b328a958fe628a9f2207d`)
- **索引条目:** Part IX — SparseCore & BarnaCore / SparseCore ISA — [返回索引](../index.md)