不論使用 gcc8 還是 gcc12,編譯參數(shù)為 -Os -march=rv32imafcxw -mabi=ilp32f 或 -Os -march=rv32imafc_xw -mabi=ilp32f
都無(wú)法獲得傳說(shuō)中的壓縮字節(jié)/半字訪問(wèn)指令。
不論使用 gcc8 還是 gcc12,編譯參數(shù)為 -Os -march=rv32imafcxw -mabi=ilp32f 或 -Os -march=rv32imafc_xw -mabi=ilp32f
都無(wú)法獲得傳說(shuō)中的壓縮字節(jié)/半字訪問(wèn)指令。
極其基礎(chǔ)的源碼:
#include
uint8_t u8;
uint16_t u16;
uint32_t u32;
uint64_t u64;
void set_u8(uint8_t x)
{
??? u8 = x;
}
uint8_t get_u8()
{
??? return u8;
}
void set_u16(uint16_t x)
{
??? u16 = x;
}
uint16_t get_u16()
{
??? return u16;
}
void set_u32(uint32_t x)
{
??? u32 = x;
}
uint32_t get_u32()
{
??? return u32;
}
void set_u64(uint64_t x)
{
??? u64 = x;
}
uint64_t get_u64()
{
??? return u64;
}
反編譯 .o 結(jié)果
Disassembly of section .text:
00000000 :
??0: ??000007b7 ???????????????lui ????a5,0x0
??4: ??00a78023 ???????????????sb ?????a0,0(a5) # 0
??8: ??8082 ???????????????????ret
0000000a :
??a: ??000007b7 ???????????????lui ????a5,0x0
??e: ??0007c503 ???????????????lbu ????a0,0(a5) # 0
?12: ??8082 ???????????????????ret
00000014 :
?14: ??000007b7 ???????????????lui ????a5,0x0
?18: ??00a79023 ???????????????sh ?????a0,0(a5) # 0
?1c: ??8082 ???????????????????ret
0000001e :
?1e: ??000007b7 ???????????????lui ????a5,0x0
?22: ??0007d503 ???????????????lhu ????a0,0(a5) # 0
?26: ??8082 ???????????????????ret
開(kāi)啟 -mrelax 后的最終結(jié)果:
Disassembly of section .text:
00010074 :
??10074: ??????67c5 ???????????????????lui ????a5,0x11
??10076: ??????0aa78c23 ???????????????sb ?????a0,184(a5) # 110b8
??1007a: ??????8082 ???????????????????ret
0001007c :
??1007c: ??????67c5 ???????????????????lui ????a5,0x11
??1007e: ??????0b87c503 ???????????????lbu ????a0,184(a5) # 110b8
??10082: ??????8082 ???????????????????ret
00010084 :
??10084: ??????80a19623 ???????????????sh ?????a0,-2036(gp) # 110c0
??10088: ??????8082 ???????????????????ret
0001008a :
??1008a: ??????80c1d503 ???????????????lhu ????a0,-2036(gp) # 110c0
??1008e: ??????8082 ???????????????????ret
誒?不對(duì)呀,別說(shuō)半字與字節(jié),連32位的怎么也沒(méi)用到壓縮指令呢
有點(diǎn)整出來(lái)了。C 代碼如下:
void set_u8c(uint8_t *a, uint8_t x)
{
??? *a = x;
}
uint8_t get_u8c(uint8_t *a)
{
??? return *a;
}
void set_u16c(uint16_t *a, uint16_t x)
{
??? *a = x;
}
uint16_t get_u16c(uint16_t *a)
{
??? return *a;
}
void set_u32c(uint32_t *a, uint32_t x)
{
??? *a = x;
}
uint32_t get_u32c(uint32_t *a)
{
??? return *a;
}
使用官方編譯器(GCC 14.2.0 from https://github.com/riscv-collab/riscv-gnu-toolchain? )
-march=rv32imafc_zcb
Disassembly of section .text:
000100b4 :
?? 100b4:?????? 890c??????????????????? sb????? a1,0(a0)
?? 100b6:?????? 8082??????????????????? ret
000100b8 :
?? 100b8:?????? 8108??????????????????? lbu???? a0,0(a0)
?? 100ba:?????? 8082??????????????????? ret
000100bc :
?? 100bc:?????? 8d0c??????????????????? sh????? a1,0(a0)
?? 100be:?????? 8082??????????????????? ret
000100c0 :
?? 100c0:?????? 8508??????????????????? lhu???? a0,0(a0)
?? 100c2:?????? 8082??????????????????? ret
000100c4 :
?? 100c4:?????? c10c??????????????????? sw????? a1,0(a0)
?? 100c6:?????? 8082??????????????????? ret
000100c8 :
?? 100c8:?????? 4108??????????????????? lw????? a0,0(a0)
?? 100ca:?????? 8082??????????????????? ret
使用官方編譯器(GCC 14.2.0 from https://github.com/riscv-collab/riscv-gnu-toolchain? )
-march=rv32imafc
Disassembly of section .text:
000100b4 :
?? 100b4:?????? 00b50023??????????????? sb????? a1,0(a0)
?? 100b8:?????? 8082??????????????????? ret
000100ba :
?? 100ba:?????? 00054503??????????????? lbu???? a0,0(a0)
?? 100be:?????? 8082??????????????????? ret
000100c0 :
?? 100c0:?????? 00b51023??????????????? sh????? a1,0(a0)
?? 100c4:?????? 8082??????????????????? ret
000100c6 :
?? 100c6:?????? 00055503??????????????? lhu???? a0,0(a0)
?? 100ca:?????? 8082??????????????????? ret
000100cc :
?? 100cc:?????? c10c??????????????????? sw????? a1,0(a0)
?? 100ce:?????? 8082??????????????????? ret
000100d0 :
?? 100d0:?????? 4108??????????????????? lw????? a0,0(a0)
?? 100d2:?????? 8082??????????????????? ret
使用沁恒/Mounriver 編譯器(MRS_Toolchain_Linux_x64_V1.92.1.tar.xz)
-march=rv32imafcxw
Disassembly of section .text:
00010094 :
?? 10094:?????? a10c??????????????????? .2byte? 0xa10c
?? 10096:?????? 8082??????????????????? ret
00010098 :
?? 10098:?????? 2108??????????????????? .2byte? 0x2108
?? 1009a:?????? 8082??????????????????? ret
0001009c :
?? 1009c:?????? a10e??????????????????? .2byte? 0xa10e
?? 1009e:?????? 8082??????????????????? ret
000100a0 :
?? 100a0:?????? 210a??????????????????? .2byte? 0x210a
?? 100a2:?????? 8082??????????????????? ret
000100a4 :
?? 100a4:?????? c10c??????????????????? sw????? a1,0(a0)
?? 100a6:?????? 8082??????????????????? ret
000100a8 :
?? 100a8:?????? 4108??????????????????? lw????? a0,0(a0)
?? 100aa:?????? 8082??????????????????? ret
使用沁恒/Mounriver 編譯器(MRS_Toolchain_Linux_x64_V1.92.1.tar.xz)
-march=rv32imafc
Disassembly of section .text:
00010094 :
?? 10094:?????? 00b50023??????????????? sb????? a1,0(a0)
?? 10098:?????? 8082??????????????????? ret
0001009a :
?? 1009a:?????? 00054503??????????????? lbu???? a0,0(a0)
?? 1009e:?????? 8082??????????????????? ret
000100a0 :
?? 100a0:?????? 00b51023??????????????? sh????? a1,0(a0)
?? 100a4:?????? 8082??????????????????? ret
000100a6 :
?? 100a6:?????? 00055503??????????????? lhu???? a0,0(a0)
?? 100aa:?????? 8082??????????????????? ret
000100ac :
?? 100ac:?????? c10c??????????????????? sw????? a1,0(a0)
?? 100ae:?????? 8082??????????????????? ret
000100b0 :
?? 100b0:?????? 4108??????????????????? lw????? a0,0(a0)
?? 100b2:?????? 8082??????????????????? ret
由此可見(jiàn),壓縮指令還是有實(shí)現(xiàn)的。但是:
與官方的 Zcb 擴(kuò)展并不兼容,可能沁恒做 RISCV 內(nèi)核比較早吧?
binutils 對(duì) xw 擴(kuò)展的支持不佳,可能精力都放在 GCC 上了,外圍忽略了。
真要代碼空間優(yōu)化,還是要深入理解 ISA、ABI 這些的。
錯(cuò)怪MounRiver了,反編譯時(shí)要添加開(kāi)關(guān):
riscv-none-elf-objdump -M xw -d a.out
這樣反匯編出來(lái)結(jié)果就是:
Disassembly of section .text:
00010094 <set_u8c>:
??10094: ??????a10c ???????????????????sb ?????a1,0(a0)
??10096: ??????8082 ???????????????????ret
00010098 <get_u8c>:
??10098: ??????2108 ???????????????????lbu ????a0,0(a0)
??1009a: ??????8082 ???????????????????ret
0001009c <set_u16c>:
??1009c: ??????a10e ???????????????????sh ?????a1,0(a0)
??1009e: ??????8082 ???????????????????ret
000100a0 <get_u16c>:
??100a0: ??????210a ???????????????????lhu ????a0,0(a0)
??100a2: ??????8082 ???????????????????ret