访存指令¶
内存加载指令¶
- 在Opcode上扩展:{b,h,w,d}来指定加载或存储传输的大小,
b表示字节,h代表半字,w代表字,d代表双字。还可以使用额外的u来指示字节或半字或者字无符号扩展到64bit(bu 表示无符号字节, hu 表示无符号半字及wu表示无符号字) - 在Opcode上扩展
i表示右源操作对象Operand1为立即数: Opcode{i}, 默认的对访存地址进行对应访存大小的移位操作,h访存半字的时候,默认左移1位,w访存字的时候,默认左移2位,d访存双字的时候,默认左移3位,汇编指令上立即数需要是访存位宽的整数倍,否则汇编器会报错。 - 在Opcode后面加上‘.u’表明不对访存地址进行默认的移位操作,偏移是立即数时,不要求是访存位宽的整数倍。
- 地址计算操作:
[Oerand0,Operand1], Operand0是寄存器,Operand1可以为寄存器或立即数,地址计算结果为 Operand0 + Operand1 - 当右源操作对象Operand1为寄存器时,可以加上{.sw, .uw}扩展,
sw表示截取该操作数的低32bit做有符号扩展,uw表示截取该操作数的低32bit做无符号扩展 <<, 对右源寄存器进行移位操作(1),(2),shamt代表左移的数量可能的值为{0, 1,2,3}, 左移0位时代表不做移位,可缺省(0)- 当右源操作对象Operand1为12bit立即数时支持表达式操作:
%lo(表达式)表示获得表达式值的低12bit,%tpcrel_lo(symbol)表示获得symbol地址的值相对于TPC偏移值的低12bit,%tprel_lo表是获得TLS变量相对于Thead Pointer寄存器的高12bit。
细节的微指令描述可以参见手册访存类指令这一章节。
汇编示意:
(0)
(1)
(2)
(3)
lhi [a2, 32], ->t /* 访存地址为 a2 + 32, 右操作对象为立即数, 显示为默认左移1位后的值, 加载出来的数据输出到T寄存器 */
lhi.u [a2, 32], ->t /* 访存地址为 a2 + 32, 加载出来的数据输出到T寄存器 */
(4)
lwi [a2, 32],->t /* 访存地址为 a2 + 32, 右操作对象为立即数, 显示为默认左移2位后的值, 加载出来的数据输出到T寄存器 */
lwi.u [a2, 32],->t /* 访存地址为 a2 + 32, 加载出来的数据输出到T寄存器 */
内存写指令¶
Opcode Operand0, [Operand1,Operand2]
Opcode Operand0, [Operand1,Operand2], ->{LL_GPR, UL_GPR} /*.a结尾的内存写指令,地址输出到LL_GPR或者UL_GPR里*/
- 在Opcode上扩展:{b,h,w,d}来指定加载或存储传输的大小,
b表示字节,h代表半字,w代表字,d代表双字。 - 在Opcode上扩展
i表示右源操作对象Operand1为立即数: Opcode{i},默认的对访存地址进行对应访存大小的移位操作,h访存半字的时候,默认左移1位,w访存字的时候,默认左移2位,d访存双字的时候,默认左移3位。要求汇编上偏移为立即数时访存位宽的整数倍,否则汇编器会报错。 - 在Opcode后面加上
u表明不对访存地址进行默认的>移位操作。偏移为立即数时,不要求其为访存位宽的整数倍。 - 地址计算操作:
[Oerand1,Operand2], Operand1是寄存器,Operand2可以为寄存器或立即数,地址计算结果为 Operand1 + Operand2 - 当Operand2为寄存器,在后面加上{.sw, .uw}扩展,
sw表示截取该操作数的低32bit做有符号扩展,uw表示截取该操作数的低32bit做无符号扩展 - 当右源操作对象Operand1为12bit的立即数时支持表达式操作:
%lo(表达式)表示获得表达式值的低12bit,%tpcrel_lo(symbol)表示获得symbol地址的值相对于TPC偏移值的低12bit,%tprel_lo表是获得TLS变量相对于Thead Pointer寄存器的低12bit
细节的微指令描述可以参见手册访存类指令这一章节。
汇编示意:
sb a1, [a2, a3] /* 访存地址为 a2 + a3 */
sh a1, [a2, a3<<1] /* 访存地址为 a2 + (a3 << 1), 默认左移1位 */
shi a1, [a2, 32] /* 访存地址为 a2 + 32,立即数要求2的倍数 */
sw a1, [a2, a3<<2] /* 访存地址为 a2 + (a3 << 2), 默认左移2位 */
swi a1, [a2, 32] /* 访存地址为 a2 + 32,立即数要求4的倍数 */
sd a1, [a2, a3<<3] /* 访存地址为 a2 + (a3 << 3), 默认左移3位 */
sdi a1, [a2, 32] /* 访存地址为 a2 + 32,立即数要求8的倍数 */
sh.u a1, [a2, a3] /* 访存地址为 a2 + a3, 不做默认左移 */
shi.u a1, [a2, 32] /* 访存地址为 a2 + 32, 不要求立即数对齐 */
sw.u a1, [a2, a3] /* 访存地址为 a2 + a3, 不做默认左移 */
swi.u a1, [a2, 32] /* 访存地址为 a2 + 32, 不要求立即数对齐 */
sd.u a1, [a2, a3] /* 访存地址为 a2 + a3, 不做默认左移 */
sdi.u a1, [a2, 32] /* 访存地址为 a2 + 32, 不要求立即数对齐 */