ESAVE¶
说明¶
异常保存块(Exception Save)
ESAVE 用于 向量数据块 或 访存数据块 执行过程中遇到异常或中断时,保存块内所有的上下文到指定的Tile寄存器中。如果软件需要进一步修改或查看这些状态,可通过 TSTORE 指令将保存至Tile寄存器的内容搬移到内存空间中。
ESAVE是一条多输出指令,其中:
- 第一个输出Tile寄存器用于保存异常块块内的私有寄存器,包括LB/LC寄存器、标量寄存器、向量寄存器、掩码寄存器等。
- 其他输出Tile寄存器用于保存异常块自身的输出Tile寄存器内容。
当前版本,由于向量数据块和访存Tile块最多可以有4个输出Tile寄存器,因此ESAVE指令最多可以有5个输出Tile寄存器。
汇编格式¶
汇编符号说明¶
| 寄存器 | 说明 | 是否可选 |
|---|---|---|
| DstTile0 | 第一个输出Tile寄存器。用于保存异常块的块内私有寄存器 | 否 |
| DstTile1 | 第二个输出Tile寄存器。用于保存异常块的第一个输出Tile寄存器内容。 | 是,如果异常块无输出Tile则不加该参数。 |
| DstTile2 | 第三个输出Tile寄存器。用于保存异常块的第二个输出Tile寄存器内容。 | 是,如果异常块没有第二个输出Tile则不加该参数。 |
| DstTile3 | 第四个输出Tile寄存器。用于保存异常块的第三个输出Tile寄存器内容。 | 是,如果异常块没有第三个输出Tile则不加该参数。 |
| DstTile4 | 第五个输出Tile寄存器。用于保存异常块的第四个输出Tile寄存器内容。 | 是,如果异常块没有第四个输出Tile则不加该参数。 |
指令编码¶
本块指令将拆分成以下指令进行编码:
- BSTART.TEPL
ESAVE - B.IOT
, ->DstTile0<32KB> - B.IOT
, ->DstTile1<32KB> - B.IOT
, ->DstTile2<32KB> - B.IOT
, ->DstTile3<32KB> - B.IOT
last, ->DstTile4<32KB>
BSTART.TEPL指令编码如下:
其中function字段编码方式为:
| function | 指令/PTO | 说明 |
|---|---|---|
| 0-29 | RESERVE | 保留 |
| 30 | ESAVE | 异常保存块,用于保存发生异常的Tile块的块内状态 |
| 31 | ERCOV | 异常恢复块,用于恢复发生异常的Tile块的块内状态 |
执行示例¶
ESAVE模版块保存异常块内状态的过程,通过伪代码示意如下:
保存块内私有寄存器¶
将异常块的块内私有寄存器状态保存至ESAVE的第一个输出Tile寄存器中:
/* --- 步骤1:保存Group间共享的寄存器状态 --- */
dst_addr = base address of DstTile0;
// 保存LB寄存器
for (int i = 0; i < 3; i++) do
DstTile[dst_addr + 2*i] = LB<i>;
end for
// 保存RI0~RI11, RO0~RO3
dst_addr += 8;
for (int i = 0; i < 16; i++) do
if (i < 12)
DstTile[dst_addr + 8*i] = RI<i>;
else
DstTile[dst_addr + 8*i] = RO<i-12>;
end for
/* --- 步骤2:保存每个Group内私有的寄存器状态 --- */
dst_addr += 128;
// group_num是处理器中并行Group的数量。对于group间串行的块,该值固定为1。
for (int gid = 0; gid < group_num; gid++) do
// 保存当前Group的TPC
DstTile[dst_addr + 0] = TPC;
// 保存LC寄存器
dst_addr += 8;
for (int i = 0; i < 3; i++) do
DstTile[dst_addr + 2*i] = LC<i>;
end for
// 保存P寄存器
DstTile[dst_addr + 8] = P;
// 保存标量寄存器
dst_addr += 16;
for (int i = 0; i < 8; i++) do
if (i < 4) then
DstTile[dst_addr + 8*i] = T#<4-i>;
else
DstTile[dst_addr + 8*i] = U#<8-i>;
end for
// 保存向量寄存器
dst_addr += 64;
for (int i = 0; i < 16; i++) do
if (i < 4)
DstTile[dst_addr + 256*i] = VT#<4-i>;
else if(i < 8)
DstTile[dst_addr + 256*i] = VU#<8-i>;
else if(i < 12)
DstTile[dst_addr + 256*i] = VM#<12-i>;
else
DstTile[dst_addr + 256*i] = VN#<16-i>;
end for
// 更新dst_addr为下个group的首地址
dst_addr += 4184;
end for
保存输出Tile的内容¶
由于发生异常或中断时,异常块的输出Tile寄存器的内容还没有更新/提交到一层架构状态中,如果此时进行状态迁移以及调度,那么发生异常前已经写过的Tile寄存器的内容将丢失。因此这些状态需要通过ESAVE模版块保存起来。
保存内容如下:
DstTile1(ESAVE) <- Output Tile0(Exception Block);
DstTile2(ESAVE) <- Output Tile1(Exception Block);
DstTile3(ESAVE) <- Output Tile2(Exception Block);
DstTile4(ESAVE) <- Output Tile3(Exception Block);
备注¶
异常数据块状态恢复过程请见ERCOV模版块介绍。