C.LH

RISC-V C.LH 指令详解

指令手册C-type

RV32/RV64 Zcb 的16位半字加载:偏移0或2字节,加载16位值后符号扩展到XLEN。

指令语法

c.lh rd', uimm(rs1')
操作数说明
RV32/RV64 Zcb,依赖 Zca;16位 CLH 格式,C 本身不提供此指令。
3位 rd'、rs1' 选择 x8–x15;字节偏移仅0或2,inst[5] 给出 uimm[1]。
成功加载16位半字后符号扩展到XLEN;基址用写回前的值。
2字节地址自然对齐;未对齐结果由 EEI 决定,访问仍须符合权限与内存区域规则。
Zcb压缩指令

指令行为说明

C.LH (Zcb, CLH格式)从rs1'加零扩展偏移加载一个半字到rd',结果符号扩展到XLEN位。rd'和rs1'仅限x8-x15。展开为lh rd',uimm(rs1')。偏移为1位无符号×2。属于Zcb,依赖Zca。

C.LH 指令解析与执行动画

只展示官方定义的 16 位字段、地址/立即数计算和架构状态;不模拟流水线、缓存、端序实现或时序。

c.lh, ()
执行环境

RV32 / RV64 Zcb (requires Zca)

有效地址为 2 的倍数时自然对齐,地址未对齐选项不适用;访问错误仍可发生。未对齐访问能否完成由 EEI 定义。内存值已按 EEI 端序解释。

x[rs1'] + 2 -> 0x0000000000002002; sext(mem[0x0000000000002002][15:0] = 0x8001) = 0xFFFFFFFFFFFF8001
16 位编码字段
15..10
funct6
100001
9..7
rs1'
010
6
bit 6: signed
1
5
uimm[1]
1
4..2
rd'
001
1..0
op
00
执行数据路径
压缩字段:rd'=001 -> x9,rs1'=010 -> x10,uimm=2。 inst[5] -> uimm[1]; other bits=0 -> 2 bytes (EXTZ)
(0x0000000000002000 + 2) mod 2^64 = 0x0000000000002002
sext(mem[0x0000000000002002][15:0] = 0x8001) = 0xFFFFFFFFFFFF8001
尚未提交架构状态。

快速理解与检索要点

RV32/RV64 Zcb 的16位半字加载:偏移0或2字节,加载16位值后符号扩展到XLEN。

CLH:inst[5] 提供 uimm[1],其余偏移位为零,inst[6] 区分有符号与无符号加载。
成功访问后符号扩展到XLEN;自然对齐为2字节,未对齐行为由 EEI 定义。

常见使用场景

半字数据加载

RV64 Zcb,x10=0x2000、mem16[0x2002] = 0x8001 且访问成功:c.lh x9, 2(x10) 得到 x9 = 0xffffffffffff8001;RV32 得到0xffff8001。

使用前检查清单

语法检查
  • RV32/RV64 Zcb,依赖 Zca;16位 CLH 格式,C 本身不提供此指令。
  • 3位 rd'、rs1' 选择 x8–x15;字节偏移仅0或2,inst[5] 给出 uimm[1]。
语义检查
  • 成功加载16位半字后符号扩展到XLEN;基址用写回前的值。
  • 2字节地址自然对齐;未对齐结果由 EEI 决定,访问仍须符合权限与内存区域规则。

容易混淆 / 常见误区

rd'、rs1' 的3位字段仅选择 x8–x15。
偏移是0或2字节;基址本身仍可能使有效地址未对齐。
加载16位值后符号扩展到XLEN;Zcb 依赖 Zca,C 扩展本身不提供此指令。

常见问题

C.LH 与 C.LHU 有什么区别?

同样从基址加0或2字节读取16位值。C.LH 符号扩展,C.LHU 零扩展;0x8001 在 RV64 分别得到0xffffffffffff8001与0x8001。

偏移为偶数就一定不会陷阱吗?

不保证。基址可能为奇数,使有效地址未对齐;即使自然对齐,访问仍须满足 EEI 的内存区域和权限规则。