Skip to content

JF/DF BarnaCore 地址处理程序包

此页上的每个地址、位偏移量、掩码和枚举值都是从 libtpu-0.0.40-cp314 轮中的 libtpu.so 读取的(内部版本 libtpu_lts_20260413_b_RC00、内部版本号 89edbbe81c5b328a958fe628a9f2207d)。 ELF 没有被剥离;存在完整的 C++ 符号。 .text.rodata VMA 等于其文件偏移量(.text 0xe63c000.rodata 0x84a0000),因此直接读取原始描述符字节。所有地址都是分析 VMA。其他版本会有所不同。

摘要

BarnaCore 地址处理程序 (BCAH) 是 Jellyfish/Dragonfish 嵌入地址个性 — tpu::TpuSequencerType = BarnaCoreAddressHandler = 2(C++ 枚举 TpuSequencerTypeToString @0x20b362e0 索引:TC=0、BCS=1、BCAH=2, SCS=3、TAC=4、TEC=5;原始线枚举 TpuSequencerTypeProto 带有额外的 INVALID=0,因此其值为 +1),是完整 BarnaCore 定序器 (BCS = 1) 的 v3 时代对应项。它的指令字是一个23字节/184位VLIW包,由直接结构字段写入填充:每个时隙编码器使用硬编码的shl N; and MASK; or常量对包的qwords/dword/word/byte进行读取-修改-写入。这是与 Pufferfish BCS 路径“根本不同”的机制,后者通过共享 BitCopy 原语与绝对位 Span 打包每个字段(请参阅 BCS 32 字节捆绑包)。这两种编码通过独立的方式在各代芯片上达到相同的嵌入数据路径系列; JF/DF 直写编解码器早于 BCS BitCopy 编解码器。

该捆绑包是一个 3 路 VLIW:一个 Common 标头(迭代状态 + 操作数选择器 + 两个立即数)、一个 ScalarSlot(控制通道)和一个 VectorSlot(5 宽矢量数据路径)。所有三个区域同时在专用的、不重叠的位位置上运行;仅*ScalarSlot(Loop/ShiftMask/Push/Branch/prog_end)内的子表格和VectorSlot*内(Store/Load/Alu0/Alu1/Result) 是互斥的。因此,一个捆绑包在单个周期中表示:推进特征长度循环、分支或结束程序、运行两个向量 ALU 操作、存储前一个嵌入行、加载下一个、排出 EUP 结果、应用每个操作数索引覆盖并携带两个 16 位文字。

此页面记录了重新实现者必须重现的三个工件:(1) 23 字节捆绑位布局Common/ScalarSlot/VectorSlot 的绝对位图、直接结构写入机制和 32 字节对齐的 23 字节 DMA 步长; (2) 5位BCS预测字段值法则和16位BarnaCorePredication.Condition枚举; (3) 立即操作数模型 — 由 YIsImm 分配的两个 16 位 ImmSlot。 Pufferfish 32 字节 BCS 序列器/通道包、标量 ISA 名册和合并的向量 ALU 操作码空间均由同级页面拥有(请参阅 交叉引用)。

重新实现,合约为:

  • 编码是直接struct write,而不是BitCopy 每个槽编码器接收相同的23字节BarnaCoreAddressHandlerBundleBits*并将其字段写入qword0 (+0) / qword1 (+8) / dword (+16) / word (+20) / 字节 (+22) 带有文字移位/掩码常量。在 BCS BitCopy Span 上对 BCAH 进行建模的重新实现者会错误地构建每个字段。
  • 每束 23 字节,32 字节对齐。 DMA 缓冲区为 (3*N)*8 - N = 23*N 字节,posix_memalign 为 32;每个包占用 23 个连续字节。
  • 不存在的时隙被编码为 kNeverExecute (0x1f),而不是作为不同的操作码。 在对任何时隙进行编码之前,调度程序会使用 kNeverExecute 预填充所有六个标量/向量时隙预测字段;当前的槽会覆盖它自己的字段。槽存在是一个预测问题。
  • 5位预测字段= condition[3:0] | (~value)<<4 Always = 0x0f (kAlwaysExecute), Never = 0x1f (kNeverExecute)。条件是嵌入迭代边界谓词字母表(16 个值,1 个别名)。
  • JF 和 DF 仅在标量槽超集上有所不同。 Dragonfish 标量槽编码器调用 Jellyfish 助手,然后添加 Branch + prog_end。相同的 23 字节帧,相同的向量槽。
个性BCAH — BarnaCore 地址处理程序; tpu::TpuSequencerType = 2(C++ 枚举:TC=0、BCS=1、BCAH=2)(水母/龙鱼)
捆绑尺寸23字节/184位,直接结构体写入; DMA 步长 23*N,32 字节对齐
位打包器none — 23 字节结构的每槽读取-修改-写入 (shl N; and MASK; or)
顶部编码器tpu::EncodeBarnaCoreAddressHandler<EncoderJf,…> @0x1e841640; <EncoderDf,…> @0x1e836ea0
捆绑调度程序EncoderJf::EncodeBarnaCoreAddressHandlerBundle @0x1e86fd80
结构图像qword0 +0(位 0..63) · qword1 +8 (64..127) · 双字 +16 (128..159) · 字 +20 (160..175) · 字节+22 (176..183)
预测律pred5 = condition + ((16*value) ^ 0x10) = condition[3:0] | (~value)<<4;默认0x0f
立即型号2 × 16 位 ImmSlot (imm_0/imm_1) 由 YIsImm @0x14169c20 分配
信心已确认(反编译的移位/掩码提取 + 23 字节跨步证明 + 原始字符串解码),除非一行另有说明

GOTCHA — BCAH 结构是 23 个字节,尽管 BundleSizeBytes 报告 BarnaCore 组件为 16。 Jellyfish 编解码器元数据大小调整器 JellyfishCodecMetadata::BundleSizeBytes @0x1ecf7460 为其 BarnaCore 组件返回 16(组件 0 = TensorCore → 41;组件1 = BarnaCore → 16;DMA 和 HBM,BundleSizeBytesForHbm @0x1ecf74c0 都同意),并且 概览 个性表和同级页面导航带有“16 B”数字。字节精确的 BCAH 编码器 证据更大:顶部编码器分配 23*N,将指针每束前进 23,最高写入位为 180 (imm_1),因此 BarnaCoreAddressHandlerBundleBits 结构图像为 23 字节/184 位。 16字节编解码器数字与xmm0(qword0+qword1)低半部分顶部编码器存储首先匹配;该存储后面是单独的双字/字/字节存储,将结构携带到 23 个字节。将 23 视为地址处理程序结构布局的权威; “16 B”标签是编解码器元数据 BarnaCore 组件大小,用作枚举存在页面上的粗略个性标签。 [置信度:已确认 — 23*N 步幅 + 每时隙位偏移量达到 180; 16是BundleSizeBytes的BarnaCore组件返回。]


1. Bundle编码模型

用途

BCAH 捆绑包是一个平面 23 字节结构 (BarnaCoreAddressHandlerBundleBits),其字段由每个时隙编码器“就地”写入。没有共享的位复制原语,也没有相对于槽的变基:每个编码器接收相同的结构指针,并将其字段以硬编码的移位写入硬编码的 qword/dword/word/byte 成员。了解此机制是读取下面每个偏移量表的先决条件 - 偏移量是从每次存储之前的 <<N 移位和 & MASK 常量恢复的,而不是从 BitCopy 立即数恢复的。

入口点

text
tpu::EncodeBarnaCoreAddressHandler<EncoderJf,…> (0x1e841640)   ── DMA buffer = 23*N, posix_memalign(.,0x20,.)
  └─ (per bundle) EncoderJf::EncodeBarnaCoreAddressHandlerBundle (0x1e86fd80)
       ├─ prefill 6 slot preds with kNeverExecute (@6/48/79/110/126/141)
       ├─ write Common header fields (compared_feature_id, indexed_*, vs0/vs1/vs2, branch_target_pc…)
       ├─ ScalarSlot encoder           (vtable +152)   — Loop/ShiftMask/Push (+ DF Branch/prog_end)
       ├─ EncodeBarnaCoreAddressHandlerVectorStore  (0x1e86e020)
       ├─ EncodeBarnaCoreAddressHandlerVectorLoad   (0x1e86e5c0)
       ├─ EncodeBarnaCoreAddressHandlerVectorAlu(0)  (0x1e86f5c0)  — lane 0
       ├─ EncodeBarnaCoreAddressHandlerVectorAlu(1)  (0x1e86f5c0)  — lane 1
       └─ EncodeBarnaCoreAddressHandlerVectorResult (0x1e86eb40)

龙鱼路径形状相同(tpu::EncodeBarnaCoreAddressHandler<EncoderDf,…> @0x1e836ea0,相同的 23*N 步幅);只有标量时隙编码器不同(§5)。

算法

c
// Models tpu::EncodeBarnaCoreAddressHandler<EncoderJf,…> @0x1e841640.
// a2 + 32 = num_bundles (int32).
function EncodeAddressHandler(program):
    n   = program.num_bundles                       // *(int*)(a2+32)
    buf = posix_memalign(align=0x20, size=23*n)      // (3*n)*8 - n = 23*n ; 32-byte aligned
    p   = buf
    for i in 0 .. n-1:
        bits = EncodeBarnaCoreAddressHandlerBundle(program.bundle[i])   // 0x1e86fd80 → 23-byte struct
        // store the 23-byte struct image, member by member:
        store_xmm(p,        bits.qword0_qword1)      // bytes 0..15  (vmovups)
        store_dword(p+16,   bits.dword)              // bytes 16..19
        store_word(p+20,    bits.word)               // bytes 20..21
        store_byte(p+22,    bits.byte)               // byte  22
        p += 23                                      // <-- the per-bundle stride is 23
    return TpuTypedHostDmaBuffer<unsigned char, 32>{ buf, 23*n }

// Models a per-slot field write (no BitCopy; direct read-modify-write):
function WriteField(struct_member, value, shift, clear_mask):
    struct_member = (value << shift) | (struct_member & clear_mask)

QUIRK — 顶部编码器将结构存储为 16 字节 vmovups xmm0 (qword0+qword1) 加上 三个标量存储(dword@16、word@20、byte@22),然后将指针前进 23。 16 字节 SIMD 存储仅涵盖位 0..127;双字/字/字节存储进位位 128..183。 DMA 缓冲区是 32 字节对齐(因此 SIMD 存储是合法的),但每个包的步幅是 23,而不是 16 或 32 — 由编码器循环中的 _R14 += 2323*N 分配大小确认。 [信心:已确认。]

注意 — 地址处理程序编码路径附加 检查字节。 TensorCore 的成帧字节机制(tpu::TpuSequencerType = 0,41 字节 HardwareBundleBits)不用作 BCAH DMA 有效负载; 23 个原始结构字节是每个包的整个有效负载。 (每通道向量 ALU 主体确实调用 EncoderJf::EncodeBundleInternal 来构建 41 字节 TensorCore 编码,然后提取其指令位并将其合并到 qword1 中 — 请参阅§2 — 但没有校验字节到达 BCAH 缓冲区。)编解码器大小调节器 JellyfishCodecMetadata::BundleSizeBytes @0x1ecf7460 为其组件 0 (TensorCore) 报告 41 / 16 对于组件 1 (BarnaCore),但地址处理程序顶部编码器直接写入 23 个字节。

功能图

功能地址角色
tpu::EncodeBarnaCoreAddressHandler<EncoderJf,…>0x1e841640顶部编码器; 23*N DMA 缓冲区,32 字节对齐
tpu::EncodeBarnaCoreAddressHandler<EncoderDf,…>0x1e836ea0DF顶部编码器;相同的 23*N 步幅
tpu::EncodeBarnaCoreAddressHandlerBundle<EncoderJf>0x1e837980std::vector<uint8> 单束形式
EncoderJf::EncodeBarnaCoreAddressHandlerBundle0x1e86fd80每包调度程序; kNeverExecute 预填充 + 公共 + 槽调用
ApplyEupResultTargetWorkaround0x1e8478a0唯一已知的读者;重用23*N步幅;修补结果区域

2. 23 字节捆绑位布局

用途

该捆绑包是 BarnaCoreAddressHandlerBundle 原型 = { common (f1), scalar (f2), vector (f3) }。 C++ 结构体映像保存三个子消息,这些子消息打包在 绝对 捆绑位位置;每个时隙编码器都以硬编码偏移量写入。与真实的原型 oneof(存储案例号)不同,编码器使用每个字段的 has-bits 和每个时隙的专用、非重叠位区域 - 因此标量、向量和公共都可以同时生效。该捆绑包是真正的 VLIW。

编码

结构体堆栈映像有五个成员:qword0(+0,位 0..63)、qword1(+8,位 64..127)、dword(+16,位 128..159)、word (+20,位 160..175),字节(+22,位 176..183)。位 181..183 被保留。调度程序用 kNeverExecute (§3) 预填充六个时隙预测字段,将 Common 标头写入 qword0/dword/word/byte,然后调用每个时隙编码器。

text
BarnaCoreAddressHandlerBundle (23 B / 184 bits; absolute bundle bits)

byte:  0        8        16       20   22
       +--------+--------+--------+----+-+
| qword0 | qword1 | dword  |word|b|
| 0..63  | 64..127| 128..159|...|.|
       +--------+--------+--------+----+-+

 ScalarSlot   ┌ Loop      bits   0..5
 (control)    │ ShiftMask pred   6..10
 Common       ┤ compared_feature_id 13..17
 (header)     │ indexed_*  (6 bools) 18..23
              │ vs0/vs1/vs2 (2b ea)  24..29
 ScalarSlot   │ Branch pred (DF)     30..34
 (control)    │ branch_type          36
              │ branch_target_pc     37..43
              └ prog_end (DF)        44
 VectorSlot   ┌ Alu0 pred           48..52
 (datapath)   │ Alu1 pred           79..83
              │ Store slot         110..125   (TABLE B)
              │ Load slot          126..140   (TABLE C)
              └ Result slot        141..146   (TABLE D)
 Common       ┌ imm_0 (16b)        149..164
 (literals)   └ imm_1 (16b)        165..180
                                    [181..183 reserved]

表 A — 顶级位图

区域源字段角色
ScalarSlot.Loop0..5Loop.loop_size_minus_one (5b @1)循环行程计数(大小 − 1)
ShiftMask 预测6..10ScalarSlot.ShiftMask.predication5 位 BCS 预测 (§3)
compared_feature_id13..17Common.compared_feature_id (5b)COMPARE_FEATURE_ID 的操作数
indexed_*18..23Common.indexed_{load_dst,store_src,alu0_x,alu0_dst,alu1_x,alu1_dst}6 个每个操作数索引覆盖
vs0/vs1/vs224..29Common.vs0/vs1/vs2(各 2b)标量寄存器选择器(§4 表 G)
Branch 预测30..34ScalarSlot.Branch.predication5 位 BCS 预测(仅限 DF)
branch_type36ScalarSlot.Branch.branch_type (1b)分支类(DF)
branch_target_pc37..43ScalarSlot.Branch.branch_target_pc (7b)分支目标 PC (DF)
prog_end44ScalarSlot.prog_end (1b)程序结束标记(DF)
Alu0 预测48..52VectorSlot.alu_0.predication5 位 BCS 预测,通道 0
Alu1 预测79..83VectorSlot.alu_1.predication5 位 BCS 预测,通道 1
Store 插槽110..125VectorSlot.store(表 B)嵌入行存储
Load 插槽126..140VectorSlot.load(表C)嵌入行负载
Result 插槽141..146VectorSlot.result(表D)EUP-结果流失
imm_0149..164Common.imm_0(f11、16b)16 位文字槽 0(<<21 进入双字,由 has 位 0x400 门控)
imm_1165..180Common.imm_1(f12、16b)16 位文字槽 1(<<37 进入双字,由 has 位 0x800 门控)

上面的 Common 头字段是从调度程序 @0x1e86fd80 恢复的:compared_feature_id at v7 |= v12<<13<<18/19/20/22/21/23 处的六个 indexed_* 布尔; vs0/vs1/vs2<<24/26/28imm_0 作为 16 位字段 <<21 放入双字(捆绑位 149,has 位 0x400),而 imm_1<<37 放入双字(捆绑位 165,has 位 0x800)。 DF branch_target_pc 由 DF 标量槽编码器 @0x1e85e8a0<<37 写入 qword0 (捆绑位 37)——一个不同的分支子表单字段,碰巧共享文字移位 37,但落在 qword0 中,而不是双字 imm_1

注意 — VectorAlu 指令体是标准 JF 矢量 ALU ISA,合并到 qword1 中。 EncodeBarnaCoreAddressHandlerVectorAlu(lane,…) @0x1e86f5c0 构建临时 isa::Bundle,调用 EncoderJf::EncodeBundleInternal(常规 JF 矢量 ALU 编码器),然后提取指令位并将它们合并到qword1 带有掩码 0xffffc000000fffff(移位 0x29/0x20/0x10)。因此,地址处理程序 ALU 操作的操作码/操作数空间等于主 JF 向量 ALU ISA;只有通道预测(通道 0 具有位 0x4 → pred @48;通道 1 具有位 0x8 → pred @79)是特定于地址处理程序的。 qword1 内合并的操作码/Vx/YSrc 位的每字段着陆位置是单独的 JF-ISA 解码(请参阅 交叉引用)。 [对合并机制的信心:高;合并字段位置在这里并不是孤立的。]


表 B — VectorSlot.Store (EncodeBarnaCoreAddressHandlerVectorStore @0x1e86e020)

r15 的结构底座; all 存储目标 qword1(+8,基位 64),因此捆绑位 = 64 + 移位。

字段捆绑钻头宽度原型场移位(在 qword1 上)
predication1105Store.predication<<46
use_loop_index1151Store.use_loop_index (f5)<<51
source (VectorRegister)1165Store.source (f7)<<52
base (BaseAddressEncoding)1212Store.base (f3)<<57
feature_length_multiplier1232Store.feature_length_multiplier (f4)<<59
push_to_concat_register1251Store.push_to_concat_register (f6)<<61

存储范围:位 110..125(16 位)。有位测试~hasword & 0x22需要source+多一个字段; basefeature_length_multiplier 宽度在存储前由 < 4 范围检查确认。

表 C — VectorSlot.Load (EncodeBarnaCoreAddressHandlerVectorLoad @0x1e86e5c0)

Load 预测跨越 qword1/dword 边界;其余字段位于双字 (+16) 窗口中。

字段捆绑钻头宽度原型场放置
predication1265Load.predication位 126,127(qword1)+ 128..130(dword)
use_loop_index1311Load.use_loop_index (f5)双字窗口 <<3
destination (VectorRegister)1325Load.destination (f6)双字窗口 <<4
base (BaseAddressEncoding)1372Load.base (f3)双字窗口 <<9
feature_length_multiplier1392Load.feature_length_multiplier (f4)双字窗口 <<11

加载范围:位 126..140(15 位)。已位测试~hasword & 0x12

表 D — VectorSlot.Result (EncodeBarnaCoreAddressHandlerVectorResult @0x1e86eb40)

字段捆绑钻头宽度原型场注释
predication1415Result.predication双字窗口 <<13
结果有效1461(插槽存在)双字位 18(= byte18 位 2)
which_destination(子表格)Result.which_destination (f2)cmp 1/2里面的@0x1e86eb40选择EUP目标形式
destination (VectorRegister)(合并中)5Result.destination (f4)EUP 结果目标 vreg

位 146(双字位 18)是 ApplyEupResultTargetWorkaround @0x1e8478a0 在 Jellyfish 芯片上重新定位的 EUP 结果存在位(它测试结果区域 — 双字位 13..17 = Result.predication,双字位 19..20 = 2 位以结果为目标的补丁)。

注意 — 存储/加载 baseResult.which_destination 枚举此处未解码。 BaseAddressEncoding(2 位 < 4 检查的 base 字段)和 VectorResultDestination (which_destination) 是共享的 JF-ISA 枚举,不是特定于地址处理程序的;上面的“字段位位置”是准确的,但值→名称名册未进行字节解码。 [信心:头寸高,价值表低——超出了这里的范围。]


3. 预测 — 5 位字段和条件枚举

用途

每个槽都带有一个 5 位预测字段,用于控制该槽是否在每次循环迭代时触发。该字段是单个打包字节:一个 4 位条件选择器加上一个 1 位极性。由于不存在的时隙预先填充有 Never (§1),因此预测字段也是时隙存在机制 - 没有单独的“时隙空”操作码。

编码

EncoderJf::EncodeBarnaCorePredication<T> 有六个相同的实例化(分支 @0x1e85ea00、存储 @0x1e86e3a0、加载 @0x1e86e920、结果 @0x1e86f020、ShiftMask @0x1e86f4a0、AluInstruction @0x1e86fc60)。每个计算:

c
// Models EncodeBarnaCorePredication<…> @0x1e85ea00.
// pred is a BarnaCorePredication proto: [+24] = condition (int32), [+28] = value (bool).
function EncodePredication(pred):
    if not pred.has_predication():
        return 0x0f                                   // kAlwaysExecute (unset default)
    if not (pred.has_condition() and pred.has_value()):
        return error("Message's predication is invalid")
    // byte-exact: pred5 = condition + ((16*value) ^ 0x10)
    return pred.condition + ((16 * pred.value) ^ 0x10)
    //  value=1  -> (16 ^ 0x10) = 0     -> pred5 = condition           (0x00..0x0f)
    //  value=0  -> ( 0 ^ 0x10) = 0x10  -> pred5 = 0x10 | condition    (0x10..0x1f)

等效于 pred5 = condition[3:0] | (~value)<<4:位 4 是 NOT(value),位 3..0 是条件 (0..15)。极性位反转条件测试 - 每个条件都有一个“execute-if”(0x00..0x0f)和一个“execute-unless”(0x10..0x1f)编码。

两个构造函数固定边界值。 MakeBarnaCorePredication(cond, value) @0x14169b20 写入 [+24] = cond[+28] = value[+16] |= 3(均为 has 位)。 Always() = Make(ALWAYS=15, value=1)15 + 0 = 0x0f(= kAlwaysExecute.rodata @0xb834cf8)。 Never() = Make(ALWAYS=15, value=0)15 + 0x10 = 0x1f(= kNeverExecute.rodata @0xb834cfc)。

注意 — 在对任何时隙进行编码之前,调度程序会使用 kNeverExecute 预填充六个时隙预测。 EncoderJf::EncodeBarnaCoreAddressHandlerBundle @0x1e86fd80kNeverExecute 掩码为 5 位,并将其复制到六个时隙预测字段中:位 6 (ShiftMask)、位 48 (Alu0)、位 79 (Alu1)、位 110(存储)、位 126(加载)、位 141(结果)— 从预填充存储验证(kNeverExecute<<6<<48 和 qword1 <<15/<<46/<<62 = 位79/110/126,并进入双字 <<13 = 位 141)。当前槽的编码器会覆盖其自己的字段。 Branch pred(位 30)预填充 — 仅当存在分支子表单时才写入。这是字节级证明,表明不存在的 BarnaCore 插槽是 Never 无操作,而不是不同的操作码。 [信心:已确认。]

表 E — BarnaCorePredication.Condition(4 位;EnumDescriptorProto @0xc017b98)

名称
0FIRST_ID
1FIRST_ID_IN_FEATURE
2NEW_FEATURE_ID
3NEW_TOKEN_ID
4NEW_SAMPLE
5LAST_ID_IN_BATCH
5ONLY_ID_IN_FEATURE_SAMPLE (别名值为 5)
6FIRST_ID_IN_BATCH
7NEW_TILE
8COMPARE_FEATURE_ID (与 Common.compared_feature_id @13..17 相比)
9REPEATED_TOKEN_FEATURE
10FIRST_ITERATION
11LAST_ITERATION
12NEW_SAMPLE_OR_TILE_FOR_THE_SAME_ID
13REPEATED_TILE_SAMPLE
14NEW_FEATURE_OR_TOKEN_FOR_THE_SAME_ID
15ALWAYS

十七个名称超过十六个值:ONLY_ID_IN_FEATURE_SAMPLE 别名 LAST_ID_IN_BATCH(均为 5),证明 allow_aliasALWAYS = 15 是默认值。该集合是嵌入表迭代边界谓词字母表 - 硬件评估的“特征行/令牌/样本/平铺/迭代边界”条件,用于控制在嵌入收集/分散处理程序的每个循环迭代上触发哪些槽。

明白了——不要将其与 BARNACORE_CHANNEL_PREDICATION_* 混淆。 该二进制文件还带有一个并行的 Pufferfish-Channel 预测枚举(BARNACORE_CHANNEL_PREDICATION_FIRST_ID…NOT_NEW_SAMPLE 等),并在名称(NOT_* 变体)中添加了显式极性。这是 BCS 通道个性的枚举,而不是此处解码的 JF/DF 地址处理程序 BarnaCorePredication.Condition — 后者通过 1 位 value 字段表示极性,而不是名称。 [置信度:已确认 - 两个枚举在二进制文件中都是不同的符号。]


4. 操作数 — 立即数和标量寄存器选择器

用途

ALU/存储/加载操作数要么命名标量寄存器,要么命名循环高级索引,要么命名立即文字。 Common 标头携带文字槽和标量寄存器选择器;每个操作数 indexed_* 布尔值选择操作数的寄存器索引是循环高级 BarnaCore-ID 还是直接寄存器。

编码 — 直接模型

Common 标头恰好有两个立即字段:捆绑位 149..164 处的 imm_0 (f11, uint32)、位 165..180 处的 imm_1 (f12, uint32) — 都是 16 位文字。引用立即数(而不是标量寄存器)的操作数通过 ProtoUtils::GetConstants<VectorAluYEncoding>(Y 操作数选择器映射,由操作数选择器值键控)→ YIsImm(u32 v, ImmSlot* slot) @0x14169c20 进行路由,它分配或重用 ImmSlot

c
// Models YIsImm @0x14169c20 (simplified).
// ImmSlot layout: [+0] half-A (u16), [+2] half-B (u16), [+4] in-use flag, [+5] dual/32-bit flag.
function YIsImm(v, slot):
    sel = GetConstants<VectorAluYEncoding>().lookup(v)    // operand-selector value -> Y encoding
    if sel found: return sel                               // operand is a register/selector, not an imm
    if (v >> 16) != 0:                                     // 32-bit literal: needs both halves of one slot
        if slot.dual_flag != 1 and slot.in_use == 0:
            slot.half_B = HIWORD(v); slot.flags = 0x0101; slot.half_A = v
            return 26                                      // dual-slot Y-encoding
        else: error("All IMM slots are occupied.")
    else:                                                  // 16-bit literal: one half of one slot
        h = LOWORD(v)
        allocate h into a free half (in_use / dual_flag bookkeeping)
        return 8 or 9 (or the zero-literal selector)       // single 16-bit Y-encoding

YIsImm 验证文字是否适合槽模型:16 位值占一个槽的一半;具有非零高位字的值占用一个槽的两半(dual 标志)。两个 16 位立即数可以共存(每个槽一个);当请求第三个不同的文字时,会触发“所有 IMM 插槽均已占用”错误。这是 Pufferfish BCS 4×16 位立即区域的 JF/DF 模拟 — 更窄(2 个槽),因为地址处理程序包是 23 个字节,而 BCS 包是 32 个字节。

表 F — 立即槽

字段捆绑钻头宽度原型场分配器
imm_0149..16416Common.imm_0(f11,uint32)YIsImm @0x14169c20
imm_1165..18016Common.imm_1(f12,uint32)YIsImm @0x14169c20

注意 — 编码器将完整的 16 位文字写入每个插槽(YIsImm 强制执行 16 位匹配)。这两个文字占用位 149..180,完全位于 184 位结构内。无论“硬件”立即字段是完整的 16 位还是更窄的子字段,都会被推断 — 编码端写入 16;没有发现解码端读取器可以交叉验证消耗的宽度。 [置信度:已确认该结构每个槽保留 16 位;推断硬件读取全部 16 个。]

编码 — 标量寄存器选择器

Common.vs0/vs1/vs2(字段 8/9/10,每个 2 位,捆绑位 24..29)在地址处理程序数据路径读取的四个物理标量源寄存器中进行选择。

表 G — BarnaCoreAddressHandlerScalarRegister(2 位;EnumDescriptorProto @0xc018caf)

名称角色
0BARNA_CORE_ID_VMEM_ADDRESS嵌入行VMEM基础(聚集/分散dest/src指针)
1GRADIENT_VMEM_ADDRESS梯度VMEM底座(后通散射源)
2BARNA_CORE_ID_WEIGHT重量 ID 寄存器
3BARNA_CORE_ID_ARGUMENTS参数指针(描述符/元数据库)

六个 indexed_* 布尔值(Common 字段 2..7,捆绑位 18..23:indexed_load_destinationindexed_store_sourceindexed_alu_0_xindexed_alu_0_destinationindexed_alu_1_xindexed_alu_1_destination) 选择每个向量操作数,其寄存器索引是循环高级 BarnaCore-ID 索引 (indexed = true) 还是直接寄存器。 compared_feature_id(f1,5 位,位 13..17)是 COMPARE_FEATURE_ID 谓词条件(§3 表 E 值 8)的操作数。


5. JF 与 DF — 标量槽超集

用途

Jellyfish 和 Dragonfish 发出相同23 字节帧和相同矢量槽;它们的区别仅在于每个标量控制通道的暴露量。龙鱼是表面比较丰富的。

编码

EncoderJf::EncodeBarnaCoreAddressHandlerScalarSlot @0x1e86f2c0 是辅助程序 …ScalarSlotHelper @0x1e86f2e0jmp,它写入 Loop(位 0..5)、ShiftMask 预测(位6)、Push有位。 EncoderDf::EncodeBarnaCoreAddressHandlerScalarSlot @0x1e85e8a0 首先调用 JF 帮助程序(继承 Loop/ShiftMask/Push),然后添加仅 Dragonfish 的子形式:Branch 预测(位 30)、branch_type (位 36)、branch_target_pc(位 37..43)和 prog_end(位 44)。

因此,Dragonfish 地址处理程序包是 Jellyfish 地址处理程序包的超集:它在标量通道中添加了一个控制流分支 + 一个程序结束标记,Jellyfish 不会通过其独立帮助程序公开该标记。两者的帧宽度(23 字节)、Common 标头和五个向量时隙相同。

字段捆绑钻头JFDF编码器
Loop.loop_size_minus_one0..5YY…ScalarSlotHelper @0x1e86f2e0
ShiftMask.predication6..10YY…ScalarSlotHelper @0x1e86f2e0
Push(有位)YY…ScalarSlotHelper @0x1e86f2e0
Branch.predication30..34YEncoderDf::…ScalarSlot @0x1e85e8a0
Branch.branch_type36YEncoderDf::…ScalarSlot @0x1e85e8a0
Branch.branch_target_pc37..43YEncoderDf::…ScalarSlot @0x1e85e8a0
prog_end44YEncoderDf::…ScalarSlot @0x1e85e8a0

我们还没有什么

  1. VectorResultDestination (Result.which_destination, f2) 值表 — 字段位位置准确(结果编码器 @0x1e86eb40 内的 cmp 1/2 子形式选择器;结果有效位 @146;双字位 19..20 处的 2 位结果目标ApplyEupResultTargetWorkaround 补丁),但值→名称名册未解码。
  2. BaseAddressEncoding(Store.base/Load.base,2位)值表 - 共享的JF-ISA枚举(< 4检查);值→名称名册不是特定于地址处理程序的,并且未在此处解码。
  3. qword1 内合并的 VectorAluInstruction 操作码/操作数位布局EncodeBarnaCoreAddressHandlerVectorAlu 委托给 EncoderJf::EncodeBundleInternal 并通过掩码 0xffffc000000fffff + 移位进行合并0x29/0x20/0x10;合并形式的每个字段操作码/Vx/YSrc 着陆位置没有被隔离(地址处理程序特定的预测 + 通道是准确的;操作码主体是 JF ISA,一个单独的解码)。
  4. 解码端逆 - 在此版本中未找到对称 BarnaCoreAddressHandler*Decoder;编码端 184 位图是权威的,但未经独立读取器交叉验证(ApplyEupResultTargetWorkaround 只读取结果区域)。
  5. imm_0/imm_1 的硬件宽度 — 编码器在每个槽写入完整的 16 位,但推断硬件是否消耗全部 16 位或较窄的子字段。

相关组件

名称关系
BarnaCoreAddressHandlerBundleBits每个时隙编码器写入的 23 字节结构
EncoderJf / EncoderDf (jellyfish::isa)JF/DF编码器开; DF 标量槽是 JF 超集
MakeBarnaCorePredication / Always / Never谓词构造函数固定 0x0f / 0x1f
YIsImm / ProtoUtils::GetConstants<VectorAluYEncoding>立即操作数分配器 + Y 操作数选择器映射
ApplyEupResultTargetWorkaround唯一已知的阅读器;重用 23*N 步幅;修补 Jellyfish 上的结果区域
HardwareBundleBits持有kAlwaysExecute=0x0f(@0xb834cf8)、kNeverExecute=0x1f(@0xb834cfc)、kPredicateRegisterCount=0x0f(@0xb834cf4)

交叉引用 {#cross-references}

  • 概览 — BarnaCore,传统嵌入加速器; BCS / BCAH 个性分割和 C++ tpu::TpuSequencerType 枚举(TC=0、BCS=1、BCAH=2;注意那里粗略的“16 B”编解码器组件标签 - 请参阅上面的 GOTCHA 以了解字节精确的 23 B 协调)
  • BCS 32 字节捆绑包 — Pufferfish BCS 音序器/通道包,本页与 BitCopy 绝对位打包路径进行对比; BCS 4×16 位立即区域是 2 时隙模型的镜像
  • BCS Scalar0/Scalar1 ISA — Pufferfish 双标量控制 + 内存操作码名册
  • 合并 ALU 位布局VectorResultDestination / BaseAddressEncoding,§2 表 B/C/D 中引用的共享 JF 向量 ALU 操作数枚举(但未进行值解码)
  • 退休证明 — BarnaCore → SparseCore 过渡; BCAH 是 v3 时代的个性,现已退休到 SparseCore
  • 指数 — 第九部分 — SparseCore 和 BarnaCore / BarnaCore(旧版 v2–v4)
  • 二进制: extracted/libtpu-0.0.40-cp314-cp314-manylinux_2_31_x86_64/libtpu/libtpu.so(构建 ID 89edbbe81c5b328a958fe628a9f2207d)