これまでの実装で、int型以外の型もサポートできているが、念のために確認しておく。
int32型よりも小さい型を扱うために、これまでに以下のノードを追加していたのだった。
llvm-myriscvx80/lib/Target/MYRISCVX/MYRISCVXInstrInfo.td
// Load/Store PatFrags. def load_a : AlignedLoad<load>; def sextloadi8_a : AlignedLoad<sextloadi8>; def zextloadi8_a : AlignedLoad<zextloadi8>; def sextloadi16_a : AlignedLoad<sextloadi16>; def zextloadi16_a : AlignedLoad<zextloadi16>; def extloadi16_a : AlignedLoad<extloadi16>; def store_a : AlignedStore<store>; def truncstorei8_a : AlignedStore<truncstorei8>; def truncstorei16_a : AlignedStore<truncstorei16>;
32ビット以外でも、16ビットと8ビットでロードストアをするためのノードを定義している。このノードを使って、ロード命令とストア命令を定義する。
/// Load and Store Instructions /// aligned mory <0b0000011, 0b010, "lw", GPR, sextloadi32_a , 0>; def SW : StoreMemory<0b0100011, 0b010, "sw", GPR, sextloadi32_a , 0>; def LB : LoadMemory <0b0000011, 0b000, "lb", GPR, sextloadi8_a , 0>; def LBU : LoadMemory <0b0000011, 0b100, "lbu", GPR, zextloadi8_a , 0>; def SB : StoreMemory<0b0100011, 0b000, "sb", GPR, truncstorei8_a , 0>; def LH : LoadMemory <0b0000011, 0b001, "lh", GPR, sextloadi16_a , 0>; def LHU : LoadMemory <0b0000011, 0b101, "lhu", GPR, zextloadi16_a , 0>; def SH : StoreMemory<0b0100011, 0b001, "sh", GPR, truncstorei16_a, 0>;
さらに、MYRISCVXのレジスタはi32型なので、charなどの符号なし整数からi32型へのロードができるように以下のパタンを追加している。
defm : LoadPattern<sextloadi8 , LB>; defm : LoadPattern<extloadi8 , LB>; defm : LoadPattern<sextloadi16 , LH>; defm : LoadPattern<extloadi16 , LH>; defm : LoadPattern<load , LW>, Requires<[IsRV32]>; defm : LoadPattern<zextloadi8 , LBU>; defm : LoadPattern<zextloadi16 , LHU>; defm : StorePattern<truncstorei8 , SB>; defm : StorePattern<truncstorei16 , SH>; defm : StorePattern<store , SW>, Requires<[IsRV32]>;
test_small_type.cpp
#include <stdint.h> int8_t test_int8_type () { volatile int8_t i8 = 0xab; int8_t i8_2 = i8 + 4; return i8_2; } uint8_t test_uint8_type () { volatile uint8_t u8 = 0xab; uint8_t u8_2 = u8 + 4U; return u8_2; }
./bin/clang ../myriscvx-tests/tests/test_small_type.cpp -c -emit-llvm --target=riscv32-unknown-elf -o test_small_type.rv32.bc ./bin/llc -march=myriscvx32 -filetype=asm test_small_type.rv32.bc -o -
生成されたコードは以下のようになった。
_Z14test_int8_typev: # @_Z14test_int8_typev # %bb.0: # %entry addi $x2, $x2, -8 addi $x10, $zero, 171 sb $x10, 4($x2) lb $x10, 4($x2) addi $x10, $x10, 4 sb $x10, 0($x2) addi $x2, $x2, 8 ret $func_end0: _Z15test_uint8_typev: # @_Z15test_uint8_typev # %bb.0: # %entry addi $x2, $x2, -8 addi $x10, $zero, 171 sb $x10, 4($x2) lb $x10, 4($x2) addi $x10, $x10, 4 sb $x10, 0($x2) addi $x2, $x2, 8 ret $func_end1:
ちゃんとlb命令、sb命令が生成されている。