@@ -48,10 +48,17 @@ unsigned RISCv64ISel::getVReg(Value* val) {
unsigned new_vreg = vreg_counter + + ;
vreg_map [ val ] = new_vreg ;
vreg_to_value_map [ new_vreg ] = val ;
vreg_type_map [ new_vreg ] = val - > getType ( ) ;
}
return vreg_map . at ( val ) ;
}
unsigned RISCv64ISel : : getNewVReg ( Type * type ) {
unsigned new_vreg = vreg_counter + + ;
vreg_type_map [ new_vreg ] = type ; // 记录这个新vreg的类型
return new_vreg ;
}
// 主入口函数
std : : unique_ptr < MachineFunction > RISCv64ISel : : runOnFunction ( Function * func ) {
F = func ;
@@ -185,7 +192,7 @@ void RISCv64ISel::selectNode(DAGNode* node) {
// 2. 使用 fmv.w.x 指令将位模式从整数寄存器移动到浮点寄存器
auto const_val = dynamic_cast < ConstantValue * > ( node - > value ) ;
auto float_vreg = getVReg ( const_val ) ;
auto temp_int_vreg = getNewVReg ( ) ; // 临时整数虚拟寄存器
auto temp_int_vreg = getNewVReg ( Type : : getIntType ( ) ) ; // 临时整数虚拟寄存器
float f_val = const_val - > getFloat ( ) ;
// 使用 reinterpret_cast 获取浮点数的32位二进制表示
@@ -235,7 +242,7 @@ void RISCv64ISel::selectNode(DAGNode* node) {
} else if ( auto global = dynamic_cast < GlobalValue * > ( ptr_val ) ) {
// 对于全局变量,先用 la 加载其地址
auto addr_vreg = getNewVReg ( ) ;
auto addr_vreg = getNewVReg ( Type : : getPointerType ( global - > getType ( ) ) ) ;
auto la = std : : make_unique < MachineInstr > ( RVOpcodes : : LA ) ;
la - > addOperand ( std : : make_unique < RegOperand > ( addr_vreg ) ) ;
la - > addOperand ( std : : make_unique < LabelOperand > ( global - > getName ( ) ) ) ;
@@ -280,7 +287,7 @@ void RISCv64ISel::selectNode(DAGNode* node) {
CurMBB - > addInstruction ( std : : move ( li ) ) ;
} else if ( val_const - > isFloat ( ) ) {
// 先将浮点数的位模式加载到整数vreg, 再用fmv.w.x移到浮点vreg
auto temp_int_vreg = getNewVReg ( ) ;
auto temp_int_vreg = getNewVReg ( Type : : getIntType ( ) ) ;
auto float_vreg = getVReg ( val_const ) ;
float f_val = val_const - > getFloat ( ) ;
@@ -327,7 +334,7 @@ void RISCv64ISel::selectNode(DAGNode* node) {
} else if ( auto global = dynamic_cast < GlobalValue * > ( ptr_val ) ) {
// 向全局变量存储
auto addr_vreg = getNewVReg ( ) ;
auto addr_vreg = getNewVReg ( Type : : getIntType ( ) ) ;
auto la = std : : make_unique < MachineInstr > ( RVOpcodes : : LA ) ;
la - > addOperand ( std : : make_unique < RegOperand > ( addr_vreg ) ) ;
la - > addOperand ( std : : make_unique < LabelOperand > ( global - > getName ( ) ) ) ;
@@ -387,7 +394,7 @@ void RISCv64ISel::selectNode(DAGNode* node) {
}
// 2. [修改] 根据基地址的类型,生成不同的指令来获取基地址
auto base_addr_vreg = getNewVReg ( ) ; // 创建一个新的临时vreg来存放基地址
auto base_addr_vreg = getNewVReg ( Type : : getIntType ( ) ) ; // 创建一个新的临时vreg来存放基地址
// 情况一:基地址是局部栈变量
if ( auto alloca_base = dynamic_cast < AllocaInst * > ( base ) ) {
@@ -760,107 +767,195 @@ void RISCv64ISel::selectNode(DAGNode* node) {
case DAGNode : : CALL : {
auto call = dynamic_cast < CallInst * > ( node - > value ) ;
// 处理函数参数, 放入a0-a7物理寄存器
size_t num_operands = node - > operands . size ( ) ;
size_t reg_arg_count = std : : min ( num_operands , ( size_t ) 8 ) ;
for ( size_t i = 0 ; i < reg_arg_count ; + + i ) {
DAGNode * arg_node = node - > operands [ i ] ;
auto arg_preg = static_cast < PhysicalReg > ( static_cast < int > ( PhysicalReg : : A0 ) + i ) ;
if ( arg_node - > kind = = DAGNode : : CONSTANT ) {
if ( auto const_val = dynamic_cast < ConstantValue * > ( arg_node - > value ) ) {
auto li = std : : make_unique < MachineInstr > ( RVOpcodes : : LI ) ;
li - > addOperand ( std : : make_unique < RegOperand > ( arg_preg ) ) ;
li - > addOperand ( std : : make_unique < ImmOperand > ( const_val - > getInt ( ) ) ) ;
CurMBB - > addInstruction ( std : : move ( li ) ) ;
// --- 步骤 1: 分配寄存器参数和栈参数 ---
// 根据RISC-V调用约定, 前8个整数/指针参数通过a0-a7传递,
// 前8个浮点参数通过fa0-fa7传递 (物理寄存器 f10-f17)。其余参数通过栈传递。
int int_reg_idx = 0 ; // a0-a7 的索引
int fp_reg_idx = 0 ; // fa0-fa7 的索引
// 用于存储需要通过栈传递的参数
std : : vector < DAGNode * > stack_args ;
for ( size_t i = 0 ; i < num_operands ; + + i ) {
DAGNode * arg_node = node - > operands [ i ] ;
Value * arg_val = arg_node - > value ;
Type * arg_type = arg_val - > getType ( ) ;
// 判断参数是浮点类型还是整型/指针类型
if ( arg_type - > isFloat ( ) ) {
if ( fp_reg_idx < 8 ) {
// --- 处理浮点寄存器参数 (fa0-fa7, 对应物理寄存器 F10-F17) ---
auto arg_preg = static_cast < PhysicalReg > ( static_cast < int > ( PhysicalReg : : F10 ) + fp_reg_idx ) ;
fp_reg_idx + + ;
if ( auto const_val = dynamic_cast < ConstantValue * > ( arg_val ) ) {
// 如果是浮点常量,需要先物化
// 1. 获取其32位二进制表示
float f_val = const_val - > getFloat ( ) ;
uint32_t float_bits = * reinterpret_cast < uint32_t * > ( & f_val ) ;
// 2. 将位模式加载到一个临时整数寄存器 (使用t0)
auto li = std : : make_unique < MachineInstr > ( RVOpcodes : : LI ) ;
li - > addOperand ( std : : make_unique < RegOperand > ( PhysicalReg : : T0 ) ) ;
li - > addOperand ( std : : make_unique < ImmOperand > ( float_bits ) ) ;
CurMBB - > addInstruction ( std : : move ( li ) ) ;
// 3. 使用fmv.w.x将位模式从整数寄存器移动到目标浮点参数寄存器
auto fmv_wx = std : : make_unique < MachineInstr > ( RVOpcodes : : FMV_W_X ) ;
fmv_wx - > addOperand ( std : : make_unique < RegOperand > ( arg_preg ) ) ;
fmv_wx - > addOperand ( std : : make_unique < RegOperand > ( PhysicalReg : : T0 ) ) ;
CurMBB - > addInstruction ( std : : move ( fmv_wx ) ) ;
} else {
// 如果已经是虚拟寄存器,直接用 fmv.s 移动
auto src_vreg = getVReg ( arg_val ) ;
auto fmv_s = std : : make_unique < MachineInstr > ( RVOpcodes : : FMV_S ) ;
fmv_s - > addOperand ( std : : make_unique < RegOperand > ( arg_preg ) ) ;
fmv_s - > addOperand ( std : : make_unique < RegOperand > ( src_vreg ) ) ;
CurMBB - > addInstruction ( std : : move ( fmv_s ) ) ;
}
} else {
// 浮点寄存器已用完,放到栈上传递
stack_args . push_back ( arg_node ) ;
}
} else { // 整数或指针参数
if ( int_reg_idx < 8 ) {
// --- 处理整数/指针寄存器参数 (a0-a7) ---
auto arg_preg = static_cast < PhysicalReg > ( static_cast < int > ( PhysicalReg : : A0 ) + int_reg_idx ) ;
int_reg_idx + + ;
if ( arg_node - > kind = = DAGNode : : CONSTANT ) {
if ( auto const_val = dynamic_cast < ConstantValue * > ( arg_val ) ) {
auto li = std : : make_unique < MachineInstr > ( RVOpcodes : : LI ) ;
li - > addOperand ( std : : make_unique < RegOperand > ( arg_preg ) ) ;
li - > addOperand ( std : : make_unique < ImmOperand > ( const_val - > getInt ( ) ) ) ;
CurMBB - > addInstruction ( std : : move ( li ) ) ;
}
} else {
auto src_vreg = getVReg ( arg_val ) ;
auto mv = std : : make_unique < MachineInstr > ( RVOpcodes : : MV ) ;
mv - > addOperand ( std : : make_unique < RegOperand > ( arg_preg ) ) ;
mv - > addOperand ( std : : make_unique < RegOperand > ( src_vreg ) ) ;
CurMBB - > addInstruction ( std : : move ( mv ) ) ;
}
} else {
// 整数寄存器已用完,放到栈上传递
stack_args . push_back ( arg_node ) ;
}
} else {
auto src_vreg = getVReg ( arg_node - > value ) ;
auto mv = std : : make_unique < MachineInstr > ( RVOpcodes : : MV ) ;
mv - > addOperand ( std : : make_unique < RegOperand > ( arg_preg ) ) ;
mv - > addOperand ( std : : make_unique < RegOperand > ( src_vreg ) ) ;
CurMBB - > addInstruction ( std : : move ( mv ) ) ;
}
}
if ( num_operands > 8 ) {
size_t stack_arg_count = num_operands - 8 ;
int stack_space = stack_arg_count * 8 ; // RV64中每个参数槽位8字节
// 2a. 在栈上分配空间
auto alloc_instr = std : : make_unique < MachineInstr > ( RVOpcodes : : ADDI ) ;
alloc_instr - > addOperand ( std : : make_unique < RegOperand > ( PhysicalReg : : SP ) ) ;
alloc_instr - > addOperand ( std : : make_unique < RegOperand > ( PhysicalReg : : SP ) ) ;
alloc_instr - > addOperand ( std : : make_unique < ImmOperand > ( - stack_spac e) ) ;
CurMBB - > addInstruction ( std : : move ( alloc_instr ) ) ;
// --- 步骤 2: 处理所有栈参数 ---
int stack_space = 0 ;
if ( ! stack_args . empty ( ) ) {
// 计算栈参数所需的总空间, RV64中每个槽位为8字节
stack_space = stack_args . siz e( ) * 8 ;
// 根据ABI, 为call分配的栈空间需要16字节对齐
if ( stack_space % 16 ! = 0 ) {
stack_space + = 16 - ( stack_space % 16 ) ;
}
// 在栈上分配空间
if ( stack_space > 0 ) {
auto alloc_instr = std : : make_unique < MachineInstr > ( RVOpcodes : : ADDI ) ;
alloc_instr - > addOperand ( std : : make_unique < RegOperand > ( PhysicalReg : : SP ) ) ;
alloc_instr - > addOperand ( std : : make_unique < RegOperand > ( PhysicalReg : : SP ) ) ;
alloc_instr - > addOperand ( std : : make_unique < ImmOperand > ( - stack_space ) ) ;
CurMBB - > addInstruction ( std : : move ( alloc_instr ) ) ;
}
// 将每个参数存储到栈上对应的位置
for ( size_t i = 0 ; i < stack_args . size ( ) ; + + i ) {
DAGNode * arg_node = stack_args [ i ] ;
Value * arg_val = arg_node - > value ;
Type * arg_type = arg_val - > getType ( ) ;
int offset = i * 8 ;
// 2b. 存储每个栈参数
for ( size_t i = 8 ; i < num_operands ; + + i ) {
DAGNode * arg_node = node - > operands [ i ] ;
unsigned src_vreg ;
// 准备源寄存器
if ( arg_node - > kind = = DAGNode : : CONSTANT ) {
// 如果是常量,先加载到临时寄存器
src _vreg = getNewVReg ( ) ;
auto const_val = dynamic_cast < ConstantValue * > ( arg_node - > value ) ;
auto li = std : : make_unique < MachineInstr > ( RVOpcodes : : LI ) ;
li - > addOperand ( std : : make_unique < RegOperand > ( src_vreg ) ) ;
li - > addOperand ( std : : make_unique < Imm Operand> ( const_val - > getInt ( ) ) ) ;
CurMBB - > addInstruction ( std : : move ( li ) ) ;
// 如果是常量, 先加载到临时vreg
if ( auto const_val = dynamic_cast < ConstantValue * > ( arg_val ) ) {
src_vreg = getNewVReg ( arg_type ) ;
if ( arg_type - > isFloat ( ) ) {
auto temp_int _vreg = getNewVReg ( Type : : getIntType ( ) ) ;
float f_val = const_val - > getFloat ( ) ;
uint32_t float_bits = * reinterpret_cast < uint32_t * > ( & f_val ) ;
auto li = std : : make_unique < MachineInstr > ( RVOpcodes : : LI ) ;
li - > addOperand ( std : : make_unique < Reg Operand> ( temp_int_vreg ) ) ;
li - > addOperand ( std : : make_unique < ImmOperand > ( float_bits ) ) ;
CurMBB - > addInstruction ( std : : move ( li ) ) ;
auto fmv_wx = std : : make_unique < MachineInstr > ( RVOpcodes : : FMV_W_X ) ;
fmv_wx - > addOperand ( std : : make_unique < RegOperand > ( src_vreg ) ) ;
fmv_wx - > addOperand ( std : : make_unique < RegOperand > ( temp_int_vreg ) ) ;
CurMBB - > addInstruction ( std : : move ( fmv_wx ) ) ;
} else {
auto li = std : : make_unique < MachineInstr > ( RVOpcodes : : LI ) ;
li - > addOperand ( std : : make_unique < RegOperand > ( src_vreg ) ) ;
li - > addOperand ( std : : make_unique < ImmOperand > ( const_val - > getInt ( ) ) ) ;
CurMBB - > addInstruction ( std : : move ( li ) ) ;
}
} else {
src_vreg = getVReg ( arg_node - > value ) ;
src_vreg = getVReg ( arg_val ) ;
}
// 计算在栈上的偏移量
int offset = ( i - 8 ) * 8 ;
// 生成 sd 指令
auto sd_instr = std : : make_unique < MachineInstr > ( RVOpcodes : : SD ) ;
sd_instr - > addOperand ( std : : make_unique < RegOperand > ( src_vreg ) ) ;
sd_instr - > addOperand ( std : : make_unique < MemOperand > (
// 根据类型选择 fsw (浮点) 或 sd (整型/指针) 存储指令
std : : unique_ptr < MachineInstr > store_instr ;
if ( arg_type - > isFloat ( ) ) {
store_instr = std : : make_unique < MachineInstr > ( RVOpcodes : : FSW ) ;
} else {
store_instr = std : : make_unique < MachineInstr > ( RVOpcodes : : SD ) ;
}
store_instr - > addOperand ( std : : make_unique < RegOperand > ( src_vreg ) ) ;
store_instr - > addOperand ( std : : make_unique < MemOperand > (
std : : make_unique < RegOperand > ( PhysicalReg : : SP ) ,
std : : make_unique < ImmOperand > ( offset )
) ) ;
CurMBB - > addInstruction ( std : : move ( sd _instr ) ) ;
CurMBB - > addInstruction ( std : : move ( store _instr ) ) ;
}
}
// --- 步骤 3: 生成CALL指令 ---
auto call_instr = std : : make_unique < MachineInstr > ( RVOpcodes : : CALL ) ;
// [协议] 如果函数有返回值,将它的目标虚拟寄存器作为第一个操作数
if ( ! call - > getType ( ) - > isVoid ( ) ) {
unsigned dest_vreg = getVReg ( call ) ;
call_instr - > addOperand ( std : : make_unique < RegOperand > ( dest_vreg ) ) ;
}
// 将函数名标签作为后续操作数
call_instr - > addOperand ( std : : make_unique < LabelOperand > ( call - > getCallee ( ) - > getName ( ) ) ) ;
// 将所有参数的虚拟寄存器也作为后续操作数, 供getInstrUseDef分析
for ( size_t i = 0 ; i < num_operands ; + + i ) {
if ( node - > operands [ i ] - > kind ! = DAGNode : : CONSTANT ) { // 常量参数已直接加载, 无需作为use
if ( node - > operands [ i ] - > kind ! = DAGNode : : CONSTANT & & node - > operands [ i ] - > kind ! = DAGNode : : FP_CONSTANT ) {
call_instr - > addOperand ( std : : make_unique < RegOperand > ( getVReg ( node - > operands [ i ] - > value ) ) ) ;
}
}
CurMBB - > addInstruction ( std : : move ( call_instr ) ) ;
if ( num_operands > 8 ) {
size_t stack_arg_count = num_operands - 8 ;
int stack_space = stack_arg_count * 8 ;
// --- 步骤 4: 处理返回值 ---
if ( ! call - > getType ( ) - > isVoid ( ) ) {
unsigned dest_vreg = getVReg ( call ) ;
if ( call - > getType ( ) - > isFloat ( ) ) {
// 浮点返回值在 fa0 (物理寄存器 F10)
auto fmv_s = std : : make_unique < MachineInstr > ( RVOpcodes : : FMV_S ) ;
fmv_s - > addOperand ( std : : make_unique < RegOperand > ( dest_vreg ) ) ;
fmv_s - > addOperand ( std : : make_unique < RegOperand > ( PhysicalReg : : F10 ) ) ; // fa0
CurMBB - > addInstruction ( std : : move ( fmv_s ) ) ;
} else {
// 整数/指针返回值在 a0
auto mv = std : : make_unique < MachineInstr > ( RVOpcodes : : MV ) ;
mv - > addOperand ( std : : make_unique < RegOperand > ( dest_vreg ) ) ;
mv - > addOperand ( std : : make_unique < RegOperand > ( PhysicalReg : : A0 ) ) ;
CurMBB - > addInstruction ( std : : move ( mv ) ) ;
}
}
// --- 步骤 5: 回收为栈参数分配的空间 ---
if ( stack_space > 0 ) {
auto dealloc_instr = std : : make_unique < MachineInstr > ( RVOpcodes : : ADDI ) ;
dealloc_instr - > addOperand ( std : : make_unique < RegOperand > ( PhysicalReg : : SP ) ) ;
dealloc_instr - > addOperand ( std : : make_unique < RegOperand > ( PhysicalReg : : SP ) ) ;
dealloc_instr - > addOperand ( std : : make_unique < ImmOperand > ( stack_space ) ) ;
CurMBB - > addInstruction ( std : : move ( dealloc_instr ) ) ;
}
// 处理返回值, 从a0移动到目标虚拟寄存器
// if (!call->getType()->isVoid()) {
// auto mv_instr = std::make_unique<MachineInstr>(RVOpcodes::MV);
// mv_instr->addOperand(std::make_unique<RegOperand>(getVReg(call)));
// mv_instr->addOperand(std::make_unique<RegOperand>(PhysicalReg::A0));
// CurMBB->addInstruction(std::move(mv_instr));
// }
break ;
}
@@ -868,17 +963,47 @@ void RISCv64ISel::selectNode(DAGNode* node) {
auto ret_inst_ir = dynamic_cast < ReturnInst * > ( node - > value ) ;
if ( ret_inst_ir & & ret_inst_ir - > hasReturnValue ( ) ) {
Value * ret_val = ret_inst_ir - > getReturnValue ( ) ;
// [V2优点] 在RETURN节点内加载常量返回值
if ( auto const_val = dynamic_cast < ConstantValue * > ( ret_val ) ) {
auto li_instr = std : : make_unique < MachineInstr > ( RVOpcodes : : LI ) ;
li_instr - > addOperand ( std : : make_unique < RegOperand > ( PhysicalReg : : A0 ) ) ;
li_instr - > addOperand ( std : : make_unique < ImmOperand > ( const_val - > getInt ( ) ) ) ;
CurMBB - > addInstruction ( std : : move ( li_instr ) ) ;
Type * ret_type = ret_val - > getType ( ) ;
if ( ret_type - > isFloat ( ) ) {
// --- 处理浮点返回值 ---
// 返回值需要被放入 fa0 (物理寄存器 F10)
if ( auto const_val = dynamic_cast < ConstantValue * > ( ret_val ) ) {
// 如果是浮点常量, 需要先物化到fa0
float f_val = const_val - > getFloat ( ) ;
uint32_t float_bits = * reinterpret_cast < uint32_t * > ( & f_val ) ;
// 1. 加载位模式到临时整数寄存器 (t0)
auto li = std : : make_unique < MachineInstr > ( RVOpcodes : : LI ) ;
li - > addOperand ( std : : make_unique < RegOperand > ( PhysicalReg : : T0 ) ) ;
li - > addOperand ( std : : make_unique < ImmOperand > ( float_bits ) ) ;
CurMBB - > addInstruction ( std : : move ( li ) ) ;
// 2. 将位模式从 t0 移动到 fa0
auto fmv_wx = std : : make_unique < MachineInstr > ( RVOpcodes : : FMV_W_X ) ;
fmv_wx - > addOperand ( std : : make_unique < RegOperand > ( PhysicalReg : : F10 ) ) ; // fa0
fmv_wx - > addOperand ( std : : make_unique < RegOperand > ( PhysicalReg : : T0 ) ) ;
CurMBB - > addInstruction ( std : : move ( fmv_wx ) ) ;
} else {
// 如果是vreg, 直接用 fmv.s 移动到 fa0
auto fmv_s = std : : make_unique < MachineInstr > ( RVOpcodes : : FMV_S ) ;
fmv_s - > addOperand ( std : : make_unique < RegOperand > ( PhysicalReg : : F10 ) ) ; // fa0
fmv_s - > addOperand ( std : : make_unique < RegOperand > ( getVReg ( ret_val ) ) ) ;
CurMBB - > addInstruction ( std : : move ( fmv_s ) ) ;
}
} else {
auto mv_instr = std : : make_unique < MachineInstr > ( RVOpcodes : : MV ) ;
mv_instr - > addOperand ( std : : make_unique < RegOperand > ( PhysicalReg : : A0 ) ) ;
mv_instr - > addOperand ( std : : make_unique < RegOperand > ( getVReg ( ret_val ) ) ) ;
CurMBB - > addInstruction ( std : : move ( mv_instr ) ) ;
// --- 处理整数/指针返回值 ---
// 返回值需要被放入 a0
// [V2优点] 在RETURN节点内加载常量返回值
if ( auto const_val = dynamic_cast < ConstantValue * > ( ret_val ) ) {
auto li_instr = std : : make_unique < MachineInstr > ( RVOpcodes : : LI ) ;
li_instr - > addOperand ( std : : make_unique < RegOperand > ( PhysicalReg : : A0 ) ) ;
li_instr - > addOperand ( std : : make_unique < ImmOperand > ( const_val - > getInt ( ) ) ) ;
CurMBB - > addInstruction ( std : : move ( li_instr ) ) ;
} else {
auto mv_instr = std : : make_unique < MachineInstr > ( RVOpcodes : : MV ) ;
mv_instr - > addOperand ( std : : make_unique < RegOperand > ( PhysicalReg : : A0 ) ) ;
mv_instr - > addOperand ( std : : make_unique < RegOperand > ( getVReg ( ret_val ) ) ) ;
CurMBB - > addInstruction ( std : : move ( mv_instr ) ) ;
}
}
}
// [V1设计保留] 函数尾声( epilogue) 不由RETURN节点生成,