現在は、int型(32ビット整数)のみLLVM IRをサポートしているが、それ以外の型をサポートしたいと思う。32ビット整数、16ビット整数、8ビット整数、そしてBool型をサポートする。
これらの値をメモリアクセスするために、AlignedLoad
を拡張して以下のノードを追加する。
llvm-myriscvx/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 defm LW : LoadM32 <0b0000011, 0b010, "lw", load_a>; defm SW : StoreM32<0b0100011, 0b010, "sw", store_a>; defm LB : LoadM32 <0b0000011, 0b000, "lb", sextloadi8_a>; defm LBU : LoadM32 <0b0000011, 0b100, "lbu", zextloadi8_a>; defm SB : StoreM32<0b0100011, 0b000, "sb", truncstorei8_a>; defm LH : LoadM32 <0b0000011, 0b001, "lh", sextloadi16_a>; defm LHU : LoadM32 <0b0000011, 0b101, "lhu", zextloadi16_a>; defm SH : StoreM32<0b0100011, 0b001, "sh", truncstorei16_a>;
さらに、MYRISCVXのレジスタはi32型なので、charなどの符号なし整数からi32型へのロードができるように以下のパタンを追加する。
def : Pat<(i32 (zextloadi1 addr:$src)), (LBU addr:$src)>; def : Pat<(i32 (zextloadi8 addr:$src)), (LBU addr:$src)>; def : Pat<(i32 (zextloadi16 addr:$src)), (LHU addr:$src)>; def : Pat<(i32 (sextloadi1 addr:$src)), (LB addr:$src)>; def : Pat<(i32 (sextloadi8 addr:$src)), (LB addr:$src)>; def : Pat<(i32 (sextloadi16 addr:$src)), (LH addr:$src)>; def : Pat<(i32 (extloadi1 addr:$src)), (LBU addr:$src)>; def : Pat<(i32 (extloadi8 addr:$src)), (LBU addr:$src)>; def : Pat<(i32 (extloadi16 addr:$src)), (LHU addr:$src)>;
さらに、符号なしの値を拡張して32ビットの符号付整数に設定するためのパタンを追加する。
def : Pat<(sext_inreg GPR:$ra, i8), (SRAI (SLLI GPR:$ra, 24), 24)>; def : Pat<(sext_inreg GPR:$ra, i16), (SRAI (SLLI GPR:$ra, 16), 16)>;
それぞれ、8ビット符号なし数の場合は24ビット左シフトしたのちに、24ビット符号付右シフトする。 一方で、16ビット符号なし数の場合は16ビット左シフトしたのちに、16ビット符号付右シフトする。
これでリビルドを行い、以下のソースをコンパイルする。
#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 -target mips-unknown-linux-gnu -c ../lbdex/input/ch7_1_other_type.cpp -emit-llvm ./bin/llc --debug -march=myriscvx32 -mcpu=simple32 -relocation-model=pic -filetype=asm ch7_1_other_type.bc -o -
_Z14test_int8_typev: # %bb.0: # %entry addi x2, x2, -8 addi x10, zero, 171 sb x10, 4(x2) lbu x10, 4(x2) addi x10, x10, 4 slli x10, x10, 24 srai x10, x10, 24 addi x2, x2, 8 ret x1 _Z15test_uint8_typev: # %bb.0: # %entry addi x2, x2, -8 addi x10, zero, 171 sb x10, 4(x2) lbu x10, 4(x2) addi x10, x10, 4 andi x10, x10, 255 addi x2, x2, 8 ret x1