跳转至

微指令

在灵犀指令集的架构定义中块指令的块体是由一系列的微指令组成,来完成具体的计算任务。微指令的汇编指令可能为如下所示形式。

Opcode                                                      
Opcode Operand0 
Opcode Operand0,Operand1
Opcode Operand0,Operand1,Operand2
Opcode Operand0,->{UL_GPR, LL_GPR}
Opcode Operand0,Operand1,->{UL_GPR, LL_GPR}
Opcode Operand0,Operand1,Operand2,->{UL_GPR, LL_GPR}
  1. 微指令在具体计算时可能会有输入并且输出计算结果。在写Operand操作对象时顺序为先左源操作对象,右源操作对象,然后再输出。后文中Operand0为左源操作对象,Operand1为右源操作对象。
  2. 微指令的输入可能是寄存器,标签,立即数。如果输入是寄存器,可能是LL_GPR以及UL_GPR,支持使用zero代表一个值恒为0的寄存器操作数。对于系统寄存器,比如访问ebstatep(架构状态基址寄存器), tp(线程私有变量基址寄存器), gp(静态全局变量基址寄存器)等,微指令访问用系统寄存器ID。具体的寄存器操作数名字可以参见架构和寄存器这一章节,系统寄存器的ID列表可以参见系统寄存器这一章节。
  3. 微指令可能无输出,如有输出,则只能是寄存器,可能输出到{UL_GPR, LL_GPR}

  4. 加上->表明微指令有输出,可以输出到UL_GPR或者是LL_GPR

  5. 输出到zero寄存器,指令执行结果不起效用。
  6. 缺省表明无输出。

下表列出了寄存器操作数的输入和输出格式:

输入寄存器操作数 输出寄存器操作数
r0 or zero r0 or zero
r1 or sp r1 or sp
r2 or a0 r2 or a0
r3 or a1 r3 or a1
r4 or a2 r4 or a2
r5 or a3 r5 or a3
r6 or a4 r6 or a4
r7 or a5 r7 or a5
r8 or a6 r8 or a6
r9 or a7 r9 or a7
r10 or ra r10 or ra
r11 or fp(s0) r11 or fp(s0)
r12 or s1 r12 or s1
r13 or s2 r13 or s2
r14 or s3 r14 or s3
r15 or s4 r15 or s4
r16 or s5 r16 or s5
r17 or s6 r17 or s6
r18 or s7 r18 or s7
r19 or s8 r19 or s8
r20 or x0 r20 or x0
r21 or x1 r21 or x1
r22 or x2 r22 or x2
r23 or x3 r23 or x3
t#1~t#4 t
u#1~u#4 u
LB0~LB2 LB0~LB2
LC0~LC2 LC0~LC2

Note

对于LB0~LB2,LC0~LC2这些系统寄存器

  • 非PAR块中需要用ssrget/ssrset才能访问。
  • PAR块中,可以用SIMT块的私有微指令直接访问。
  • 当前版本微指令均不支持多输出。

微指令输出规范:

  • 微指令的Opcode决定了该微指令是否有输出
  • 有输出的微指令输出部分不可缺省,否则汇编器会报指令格式错误

Opcode的识别

对于Opcode的识别,首先确定其所在的块类型,进而通过对Opcode进行扩展来区分不同的指令,不同精度的浮点指令,以及原子指令的不同操作等。

  • 在Opcode后面加上w:Opcode{w}表明进行低32bit有符号扩展
  • 在Opcode后面加上u:Opcode{u}表明进行无符号操作
  • 在Opcode后面加上i:Opcode{i}表明右源操作对象为立即数
  • 在Opcode后面加上{.eq, .ne, .lt, .ge, .ltu, .geu, .and, .or}:Opcode{.eq, .ne, .lt, .ge, .ltu, .geu, .and, .or}来表明判断成立的条件,.eq表示相等则判断成立,.ne表示不相等则判断成立,.lt表示有符号左源小于有符号右源则条件成立, ge表示有符号左源大于有符号右源则条件成立。在.lt.ge的基础上加上u表明做无符号比较,.and.or分别表示逻辑与和逻辑或,i表明右源操作对象为立即数的比较
  • 在Opcode前面加上c.:c.Opcode表明该指令为压缩指令,编码长度为16bit
  • 浮点精度:Opcode{.fd, .fs, .fh, fb}, .fd代表64bit双精度浮点类型, .fs代表32bit单精度浮点类型, .fh代表16bit半精度浮点类型,.fb代表8bit的低精度浮点类型,仅限于浮点指令
  • 原子操作:Opcode{.aq, .rl, .aqrl}, .aq代表Acquire, .rl代表Release, .aqrl代表AcquireRelease, 仅限原子指令

Operand操作

支持对Operand的移位,地址计算,取址,算术操作,逻辑操作等操作

  • Operand的类型为寄存器时,支持如下操作:

    • 算术操作Operand{.sw, .uw, .neg} 仅限对寄存器进行, sw表示截取该操作数的低32bit做有符号扩展,uw表示截取该操作数的低32bit做无符号扩展,neg表示对该操作数位取反加1。
    • 逻辑操作Operand{.sw, .uw, .not},仅限对寄存器进行 .not表示对该操作数取反。
    • 移位操作:Operand1<<shamt, 对Operand1左移shamt位。
  • Operand为立即数和标签时,可支持常量值和立即数的取值操作,仅限整数计算类指令,访存指令,常量类指令:

    • 使用绝对值:%hi(表达式)表示获得表达式计算结果的高20bit, %lo(表达式)表示获得表达式计算结果的低12bit。
    • 使用相对TPC值:%tpcrel_hi(symbol)表示获得symbol地址相对于当前TPC的高20bit, %got_tpcrel_hi(symbol)表示获得symbol在GOT表上的表项地址相对于当前TPC的高20bit’,%tpcrel_lo(label)需要获得高位symbol地址相对于label地址的低12bit。
    • 使用相对Thread Pointer的值:%tprel_hi表示获得TLS变量相对于Thead Pointer寄存器的高20bit,%tprel_lo表示获得TLS变量相对于Thead Pointer寄存器的低12bit。
    • 使用相对Global Pointer的值:%gprel_hi表示获得全局变量相对于Global Pointer寄存器的高20bit,gprel_lo表示获得全局变量相对于Global Pointer寄存器的低12bit。
  • 地址计算操作:[Operand0]或者[Operand0,Operand1], 仅限对寄存器或立即数Operand做地址计算, Operand0是寄存器,Operand1可以为寄存器或立即数, 详见访存指令

可以对同一个Operand进行多个操作,如[Operand1, Operand2.sw<<shamt]

寄存器类型的operand扩展设计

寄存器类型Operand增加位宽指示的设计,其目的是为了给硬件提示,从而提升SIMT块中寄存器资源的利用率。使用方式如下:

  • 输出操作数标识:Operand{.b, .h, .w, .d},.b, .h, .w, .d分别表示寄存器操作数宽度为8bit,16bit,32bit,64bit。该扩展设计可以叠加其他Operand的基础操作使用,比如移位,根据具体指令确定。
  • 输入操作数标识:Operand{.fd, .fs, .fh, .fb, .bf, .flb, .d, .uw, .uh, .ub, .sw, .sh, .sb},其中.fd, .fs, .fh, .fb, .bf, .flb用于表示寄存器操作数类型的浮点类型及相应的位宽,.d, .uw, .uh, .ub, .sw, .sh, .sb用于表示寄存器操作数为整型及相应的位宽。

块体微指令的使用

块体微指令分为两个大类:公有微指令及私有微指令,通常情况下,块指令的块体微指令是由公有微指令配合部分私有微指令组成。