system: [SYSTEM]

user: 6. 扩展指令 对于高精度计算来说，40位整数和40位浮点数可能不足，故可定义80位双精度的整数和浮点操作。这部分指令不是所有40位芯片都必须实现的，故作为可选的扩展指令。扩展指令从128号指令开始，即操作码的最高位为1，除了此处定义的双精度操作指令，预留的指令空间较多，需要实现特殊功能的芯片可以方便地扩展指令集。 实现双精度计算的简单方法是将通用寄存器的位宽加倍，从40位扩展到80位，原有的基本指令只使用其中40位，故不受影响，这个方法的缺点是要增加硬件成本。另一个较为经济的做法是通用寄存器的位宽不变，只是将相邻的两个寄存器合并起来达到80位宽度，这个方法能降低硬件制造成本，缺点是双精度操作所用的通用寄存器数量减少。综合考虑，如果双精度操作使用不多，可维持原有寄存器设计，以尽量经济，如果双精度操作十分密集，则应将通用寄存器宽度加倍，以获得更好性能。 寄存器和存储器之间的载入和存储操作采用已有指令，即载入十字节的指令LT: rd， rs1，imm，和存储十字节的指令ST: rs2， rs1，imm，转移的数据可以是整数，也可以是浮点数，因为占用的空间大小一样，为方便使用，也可改写为伪指令。 80位双精度浮点数参考前述的40位浮点数格式，可以用1位存符号，11位存指数，剩下68位存尾数。指数的范围为−1022~1023，能表示的大小范围为 ± 2 * 2 1023 ≈ ± 1.798 * 10 308 ，尾数的精度可达到 68 ⋅ log 10 2 ≈ 20.47 ，即有20位有效数字，对高精度计算十分有用。 6.1. 双精度浮点数运算指令 双精度浮点数运算指令包含了80位浮点数加、减、乘、除、平方根指令，如表15所示，由于很多工程计算中有求乘积后立即相加或相减的运算，故设置双精度浮点乘加指令和双精度浮点乘减指令。 Table 1 5 Double-precision floating-point number operation instruction 编号 名称 格式 长 说明 136 浮点加 DADD: rd， rs1， rs2 4 双精度浮点数[rd]=[rs1]+[rs2] 137 浮点减 DSUB: rd， rs1， rs2 4 双精度浮点数[rd]=[rs1]−[rs2] 138 浮点乘 DMUL: rd， rs1， rs2 4 双精度浮点数[rd]=[rs1]*[rs2] 139 浮点除 DDIV: rd， rs1， rs2 4 双精度浮点数[rd]=[rs1]/[rs2]， 128 平方根 DSQRT: rd， rs1 3 双精度浮点数[rd]=sqrt([rs1]) 160 浮点乘加 DMADD: rd， rs1， rs2， rs3 5 双精度浮点数[rd]=[rs1]*[rs2]+[rs3] 161 浮点乘减 DMSUB: rd， rs1， rs2， rs3 5 双精度浮点数[rd]=[rs1]*[rs2]−[rs3] 表15. 双精度浮点数运算指令 6.2. 双精度浮点数比较操作指令 双精度浮点数比较操作指令包含判断双精度浮点数类型、小于、小于等于、等于、最小和最大指令，如表16所示，其中双精度浮点数类型与单精度浮点数类型的判断是相似的。 Table 1 6 Double-precision floating-point number comparison operation instruction 编号 名称 格式 长 说明 129 双精度浮点数类型 DCLS: rd， rs1 3 判断[rs1]的浮点数类型，类型码写入rd 140 双精度浮点小于 DLT: rd， rs1， rs2 4 如果[rs1]<[rs2]，[rd]=1，否则为0 141 双精度浮点小于等于 DLE: rd， rs1， rs2 4 如果[rs1]<=[rs2]，[rd]=1，否则为0 142 双精度浮点等于 DEQ: rd， rs1， rs2 4 如果[rs1]==[rs2]，[rd]=1，否则为0 143 双精度浮点最小值 DMIN: rd， rs1， rs2 4 将[rs1]和[rs2]中最小值放置到rd中 144 双精度浮点最大值 DMAX: rd， rs1， rs2 4 将[rs1]和[rs2]中最大值放置到rd中 表16. 双精度浮点数比较操作指令 6.3. 双精度浮点数转换指令 双精度浮点数转换指令包含80位浮点数和80位有符号长整数和无符号长整数之间的转换操作指令，如表17所示。不提供40位整数和80位双精度浮点数之间的直接转换操作，因为精度损失太大。要实现40位整数和双精度浮点之间的转换，可以先将40位整数扩展为80位整数，再转换为双精度浮点数。由于单精度浮点数和双精度浮点数的指数位宽度一样，所以它们之间的转换是无缝的，即取前40位为单精度浮点数，取完整的80位为双精度浮点数。双精度浮点数的符号操作与单精度浮点数相同，都是对最高位即符号位的处理，故无需另外指令。 Table 1 7 Double-precision floating-point number conversion operation instruction 编号 名称 格式 长 说明 130 长整数到双精度浮点 FLD: rd， rs 3 rs中的80位整数转换为双精度浮点数 131 双精度浮点到长整数 FDL: rd， rs 3 rs中的双精度浮点数转换为80位整数 132 无符号长整数到双精度浮点 FULD: rd， rs 3 rs中的80位无符号整数转换为双精度浮点数 133 双精度浮点到无符号长整数 FDUL: rd， rs 3 rs中的双精度浮点数转换为80位无符号整数 表17. 双精度浮点数转换操作指令 6.4. 长整数运算指令 长整数为80位二进制整数，分为有符号和无符号两类。对80位无符号整数，表示范围为0~2 80 −1，对80位有符号数，最高位区分符号，表示范围为−2 79 +1~2 79 −1。长整数的运算指令包含加减、乘除、求余等功能，如表18所示。如果希望得到两个80位整数相乘的完整160位结果，可以融合两条指令连续执行“LMUL: rd， rs1， rs2; LMULH[U]: rd+2， rs1， rs2”，此处将160位结果的小端部分放在前，大端部分放在后，便于和80位整数无缝转换。另提供复制80位内容的操作指令LMOV和长整数自加操作指令LINCB。 Table 1 8 Long integer operation instruction 编号 名称 格式 长 说明 145 长整数加法 LADD: rd， rs1， rs2 4 对长整数计算[rd]=[rs1]+[rs2] 146 长整数减法 LSUB: rd， rs1， rs2 4 对长整数计算[rd]=[rs1]-[rs2] 134 长整数自加操作 LINCB: rd， imm 3 对长整数计算[rd]+=imm 135 复制长整数内容 LMOV: rd， rs1 3 将rs1中80位内容复制到rd寄存器 147 长整数相乘低位 LMUL: rd， rs1， rs2 4 rd保存长整数[rs1]*[rs2]的低80位 148 长整数相乘高位 LMULH: rd， rs1， rs2 4 rd保存长整数[rs1]*[rs2]的高80位 149 无符号长整数相乘高位 LMULHU: rd， rs1， rs2 4 rd保存无符号长整数[rs1]*[rs2]的高80位 150 相除 LDIV: rd， rs1， rs2 4 长整数相除[rd]=[rs1]/[rs2] 151 无符号长整数相除 LDIVU: rd， rs1， rs2 4 无符号长整数相除[rd]=[rs1]/[rs2] 152 求余 LREM: rd， rs1， rs2 4 长整数求余[rd]=[rs1]%[rs2] 153 无符号长整数求余 LREMU: rd， rs1， rs2 4 无符号长整数求余[rd]=[rs1]%[rs2] 表18. 长整数运算指令 6.5. 长整数原子存储操作指令 长整数原子存储指令对80位的长整数进行原子性操作，便于多个核心并行处理长整数，支持的操作包括原子比较交换、交换、加减和逻辑操作，如表19所示。 Table 1 9 Long integer atomic storage operation instruction 编号 名称 格式 长 说明 154 长整数原子比较交换 AMLCMPS: rd， rs2， rs1 4 以[rs1]为地址读出长整数，与[rd]比较，相等则将[rs2]存储到[rs1]位置，不相等则将rd设为读出值 155 长整数原子交换 AMLSWAP: rd， rs2， rs1 4 以[rs1]为地址，读出长整数存放到rd寄存器中，将[rs2]存储到[rs1]为地址的位置，然后[rs2]=[rd] 156 长整数原子加 AMLADD: rd， rs2， rs1 4 以[rs1]为地址，读出长整数存放到rd寄存器中，[rs2]+=[rd]，将[rs2]存储到[rs1]位置 157 长整数原子与 AMLAND: rd， rs2， rs1 4 从[rs1]读出长整数存放到rd寄存器中，[rs2]&=[rd]，将[rs2]存储到[rs1]位置 158 长整数原子或 AMLOR: rd， rs2， rs1 4 从[rs1]读出长整数存放到rd寄存器中，[rs2]|=[rd]，将[rs2]存储到[rs1]位置 159 长整数原子异或 AMLXOR: rd， rs2， rs1 4 从[rs1]读出长整数存放到rd寄存器中，[rs2]|^=[rd]，将[rs2]存储到[rs1]位置 表19. 长整数原子存储操作指令