@ -13,6 +13,7 @@ const std::vector<RISCv32CodeGen::PhysicalReg> RISCv32CodeGen::allocable_regs =
std : : string RISCv32CodeGen : : reg_to_string ( PhysicalReg reg ) {
switch ( reg ) {
case PhysicalReg : : S0 : return " s0 " ;
case PhysicalReg : : T0 : return " t0 " ; case PhysicalReg : : T1 : return " t1 " ;
case PhysicalReg : : T2 : return " t2 " ; case PhysicalReg : : T3 : return " t3 " ;
case PhysicalReg : : T4 : return " t4 " ; case PhysicalReg : : T5 : return " t5 " ;
@ -27,7 +28,6 @@ std::string RISCv32CodeGen::reg_to_string(PhysicalReg reg) {
std : : string RISCv32CodeGen : : code_gen ( ) {
std : : stringstream ss ;
ss < < " .text \n " ;
ss < < module_gen ( ) ;
return ss . str ( ) ;
}
@ -35,16 +35,36 @@ std::string RISCv32CodeGen::code_gen() {
std : : string RISCv32CodeGen : : module_gen ( ) {
std : : stringstream ss ;
// 生成全局变量(数据段)
for ( const auto & global : module - > getGlobals ( ) ) {
bool has_ globals = ! module - > getGlobals ( ) . empty ( ) ;
if ( has_globals ) {
ss < < " .data \n " ;
ss < < " .globl " < < global - > getName ( ) < < " \n " ;
ss < < global - > getName ( ) < < " : \n " ;
ss < < " .word 0 \n " ; // 假设初始化为0
for ( const auto & global : module - > getGlobals ( ) ) {
ss < < " .globl " < < global - > getName ( ) < < " \n " ;
ss < < global - > getName ( ) < < " : \n " ;
const auto & init_values = global - > getInitValues ( ) ;
for ( size_t i = 0 ; i < init_values . getValues ( ) . size ( ) ; + + i ) {
auto val = init_values . getValues ( ) [ i ] ;
auto count = init_values . getNumbers ( ) [ i ] ;
if ( auto constant = dynamic_cast < ConstantValue * > ( val ) ) {
for ( unsigned j = 0 ; j < count ; + + j ) {
if ( constant - > isInt ( ) ) {
ss < < " .word " < < constant - > getInt ( ) < < " \n " ;
} else {
float f = constant - > getFloat ( ) ;
uint32_t float_bits = * ( uint32_t * ) & f ;
ss < < " .word " < < float_bits < < " \n " ;
}
}
}
}
}
}
// 生成函数(文本段)
ss < < " .text \n " ;
for ( const auto & func : module - > getFunctions ( ) ) {
ss < < function_gen ( func . second . get ( ) ) ;
if ( ! module - > getFunctions ( ) . empty ( ) ) {
ss < < " .text \n " ;
for ( const auto & func : module - > getFunctions ( ) ) {
ss < < function_gen ( func . second . get ( ) ) ;
}
}
return ss . str ( ) ;
}
@ -54,19 +74,22 @@ std::string RISCv32CodeGen::function_gen(Function* func) {
// 函数标签
ss < < " .globl " < < func - > getName ( ) < < " \n " ;
ss < < func - > getName ( ) < < " : \n " ;
// 序言:保存 ra, 分配堆栈
bool is_leaf = true ; // 简化假设
ss < < " addi sp, sp, -16 \n " ;
ss < < " sw ra, 12(sp) \n " ;
// 寄存器分配
auto alloc = register_allocation ( func ) ;
// 序言:分配堆栈,保存 ra 和 s0, 设置帧指针
int stack_size = alloc . stack_size ;
ss < < " addi sp, sp, - " < < stack_size < < " \n " ;
ss < < " sw ra, " < < ( stack_size - 4 ) < < " (sp) \n " ;
ss < < " sw s0, " < < ( stack_size - 8 ) < < " (sp) \n " ;
ss < < " mv s0, sp \n " ;
// 生成基本块代码
for ( const auto & bb : func - > getBasicBlocks ( ) ) {
ss < < basicBlock_gen ( bb . get ( ) , alloc ) ;
}
// 结尾:恢复 ra, 释放堆栈
ss < < " lw ra, 12 (sp) \n " ;
ss < < " addi sp , sp, 16 \n " ;
// 结尾:恢复 ra 和 s0 ,释放堆栈
ss < < " lw ra, " < < ( stack_size - 4 ) < < " (sp) \n " ;
ss < < " lw s0 , " < < ( stack_size - 8 ) < < " (sp) \n " ;
ss < < " addi sp, sp, " < < stack_size < < " \n " ;
ss < < " ret \n " ;
return ss . str ( ) ;
}
@ -75,83 +98,175 @@ std::string RISCv32CodeGen::basicBlock_gen(BasicBlock* bb, const RegAllocResult&
std : : stringstream ss ;
ss < < bb - > getName ( ) < < " : \n " ;
for ( const auto & inst : bb - > getInstructions ( ) ) {
auto riscv_insts = instruction_gen ( inst . get ( ) ) ;
auto riscv_insts = instruction_gen ( inst . get ( ) , alloc );
for ( const auto & riscv_inst : riscv_insts ) {
ss < < " " < < riscv_inst . opcode ;
for ( size_t i = 0 ; i < riscv_inst . operands . size ( ) ; + + i ) {
if ( i > 0 ) ss < < " , " ;
if ( riscv_inst . operands [ i ] . kind = = Operand : : Kind : : Reg ) {
auto it = alloc . reg_map . find ( riscv_inst . operands [ i ] . value ) ;
if ( it ! = alloc . reg_map . end ( ) ) {
ss < < reg_to_string ( it - > second ) ;
} else {
auto stack_it = alloc . stack_map . find ( riscv_inst . operands [ i ] . value ) ;
if ( stack_it ! = alloc . stack_map . end ( ) ) {
ss < < stack_it - > second < < " (sp) " ;
} else {
ss < < " % " < < riscv_inst . operands [ i ] . value - > getName ( ) ;
}
}
} else if ( riscv_inst . operands [ i ] . kind = = Operand : : Kind : : Imm ) {
ss < < riscv_inst . operands [ i ] . label ;
} else {
ss < < riscv_inst . operands [ i ] . label ;
}
}
ss < < " \n " ;
ss < < " " < < riscv_inst < < " \n " ;
}
}
return ss . str ( ) ;
}
std : : vector < RISCv32CodeGen : : RISCv32Inst > RISCv32CodeGen : : instruction_gen ( Instruction * inst ) {
std : : vector < RISCv32Inst > insts ;
std : : vector < std : : string > RISCv32CodeGen : : instruction_gen ( Instruction * inst , const RegAllocResult & alloc ) {
std : : vector < std : : string > insts ;
if ( auto bin = dynamic_cast < BinaryInst * > ( inst ) ) {
std : : string lhs_reg = " t0 " ;
std : : string rhs_reg = " t1 " ;
std : : string dst_reg = " t2 " ;
// 加载 LHS
if ( auto lhs_const = dynamic_cast < ConstantValue * > ( bin - > getLhs ( ) ) ) {
if ( lhs_const - > isInt ( ) ) {
insts . push_back ( " li " + lhs_reg + " , " + std : : to_string ( lhs_const - > getInt ( ) ) ) ;
}
} else {
auto lhs_it = alloc . stack_map . find ( bin - > getLhs ( ) ) ;
if ( lhs_it ! = alloc . stack_map . end ( ) ) {
insts . push_back ( " lw " + lhs_reg + " , " + std : : to_string ( lhs_it - > second ) + " (s0) " ) ;
}
}
// 加载 RHS
if ( auto rhs_const = dynamic_cast < ConstantValue * > ( bin - > getRhs ( ) ) ) {
if ( rhs_const - > isInt ( ) ) {
insts . push_back ( " li " + rhs_reg + " , " + std : : to_string ( rhs_const - > getInt ( ) ) ) ;
}
} else {
auto rhs_it = alloc . stack_map . find ( bin - > getRhs ( ) ) ;
if ( rhs_it ! = alloc . stack_map . end ( ) ) {
insts . push_back ( " lw " + rhs_reg + " , " + std : : to_string ( rhs_it - > second ) + " (s0) " ) ;
}
}
// 执行二元操作
std : : string opcode ;
if ( bin - > getKind ( ) = = BinaryInst : : kAdd ) opcode = " add " ;
else if ( bin - > getKind ( ) = = BinaryInst : : kSub ) opcode = " sub " ;
else if ( bin - > getKind ( ) = = BinaryInst : : kMul ) opcode = " mul " ;
else return insts ; // 其他操作未实现
insts . emplace _back( opcode , std : : vector < Operand > {
{ Operand : : Kind : : Reg , bin } ,
{ Operand : : K ind: : Reg , bin - > getLhs ( ) } ,
{ Operand : : Kind : : Reg , bin - > getRhs ( ) }
} ) ;
else return insts ; // 未支持的操作
insts . push _back( opcode + " " + d st_reg + " , " + lhs_reg + " , " + rhs_reg ) ;
// 存储结果
auto dst_it = alloc . stack_map . f ind( bin ) ;
if ( dst_it ! = alloc . stack_map . end ( ) ) {
insts . push_back ( " sw " + dst_reg + " , " + std : : to_string ( dst_it - > second ) + " (s0) " ) ;
}
} else if ( auto load = dynamic_cast < LoadInst * > ( inst ) ) {
insts . emplace_back ( " lw " , std : : vector < Operand > {
{ Operand : : Kind : : Reg , load } ,
{ Operand : : K ind: : Label , load - > getPointer ( ) - > getName ( ) }
} ) ;
std : : string dst_reg = " t1 " ;
// 检查是否为局部变量
auto ptr_it = alloc . stack_map . f ind( load - > getPointer ( ) ) ;
if ( ptr_it ! = alloc . stack_map . end ( ) ) {
// 局部变量:直接从栈加载
insts . push_back ( " lw " + dst_reg + " , " + std : : to_string ( ptr_it - > second ) + " (s0) " ) ;
auto dst_it = alloc . stack_map . find ( load ) ;
if ( dst_it ! = alloc . stack_map . end ( ) ) {
insts . push_back ( " sw " + dst_reg + " , " + std : : to_string ( dst_it - > second ) + " (s0) " ) ;
}
} else {
// 全局变量:加载地址并读取
std : : string ptr_reg = " t0 " ;
insts . push_back ( " la " + ptr_reg + " , " + load - > getPointer ( ) - > getName ( ) ) ;
insts . push_back ( " lw " + dst_reg + " , 0( " + ptr_reg + " ) " ) ;
auto dst_it = alloc . stack_map . find ( load ) ;
if ( dst_it ! = alloc . stack_map . end ( ) ) {
insts . push_back ( " sw " + dst_reg + " , " + std : : to_string ( dst_it - > second ) + " (s0) " ) ;
}
}
} else if ( auto store = dynamic_cast < StoreInst * > ( inst ) ) {
insts . emplace_back ( " sw " , std : : vector < Operand > {
{ Operand : : Kind : : Reg , store - > getValue ( ) } ,
{ Operand : : Kind : : Label , store - > getPointer ( ) - > getName ( ) }
} ) ;
std : : string val_reg = " t0 " ;
// 加载值
if ( auto val_const = dynamic_cast < ConstantValue * > ( store - > getValue ( ) ) ) {
if ( val_const - > isInt ( ) ) {
insts . push_back ( " li " + val_reg + " , " + std : : to_string ( val_const - > getInt ( ) ) ) ;
}
} else {
auto val_it = alloc . stack_map . find ( store - > getValue ( ) ) ;
if ( val_it ! = alloc . stack_map . end ( ) ) {
insts . push_back ( " lw " + val_reg + " , " + std : : to_string ( val_it - > second ) + " (s0) " ) ;
}
}
// 检查是否为局部变量
auto ptr_it = alloc . stack_map . find ( store - > getPointer ( ) ) ;
if ( ptr_it ! = alloc . stack_map . end ( ) ) {
// 局部变量:直接存储到栈
insts . push_back ( " sw " + val_reg + " , " + std : : to_string ( ptr_it - > second ) + " (s0) " ) ;
} else {
// 全局变量:加载地址并存储
std : : string ptr_reg = " t1 " ;
insts . push_back ( " la " + ptr_reg + " , " + store - > getPointer ( ) - > getName ( ) ) ;
insts . push_back ( " sw " + val_reg + " , 0( " + ptr_reg + " ) " ) ;
}
} else if ( auto ret = dynamic_cast < ReturnInst * > ( inst ) ) {
if ( ret - > hasReturnValue ( ) ) {
if ( auto ret_const = dynamic_cast < ConstantValue * > ( ret - > getReturnValue ( ) ) ) {
if ( ret_const - > isInt ( ) ) {
insts . push_back ( " li a0, " + std : : to_string ( ret_const - > getInt ( ) ) ) ;
}
} else {
auto ret_it = alloc . stack_map . find ( ret - > getReturnValue ( ) ) ;
if ( ret_it ! = alloc . stack_map . end ( ) ) {
insts . push_back ( " lw a0, " + std : : to_string ( ret_it - > second ) + " (s0) " ) ;
}
}
}
// 栈恢复在 function_gen 中处理
}
return insts ;
}
RISCv32CodeGen : : RegAllocResult RISCv32CodeGen : : register_allocation ( Function * func ) {
RegAllocResult result ;
int stack_offset = 0 ; // 从 0 开始,每槽增 4
std : : set < Value * > allocated ; // 跟踪已分配的变量
for ( const auto & bb : func - > getBasicBlocks ( ) ) {
for ( const auto & inst : bb - > getInstructions ( ) ) {
// 为局部变量分配栈空间
if ( auto store = dynamic_cast < StoreInst * > ( inst . get ( ) ) ) {
auto ptr = store - > getPointer ( ) ;
if ( result . stack_map . find ( ptr ) = = result . stack_map . end ( ) & & allocated . find ( ptr ) = = allocated . end ( ) ) {
result . stack_map [ ptr ] = stack_offset ;
stack_offset + = 4 ;
allocated . insert ( ptr ) ;
}
} else if ( auto bin = dynamic_cast < BinaryInst * > ( inst . get ( ) ) ) {
// 为二元操作结果分配栈空间
if ( result . stack_map . find ( bin ) = = result . stack_map . end ( ) & & allocated . find ( bin ) = = allocated . end ( ) ) {
result . stack_map [ bin ] = stack_offset ;
stack_offset + = 4 ;
allocated . insert ( bin ) ;
}
} else if ( auto ret = dynamic_cast < ReturnInst * > ( inst . get ( ) ) ) {
// 为返回值分配栈空间(如果需要)
if ( ret - > hasReturnValue ( ) & & ! dynamic_cast < ConstantValue * > ( ret - > getReturnValue ( ) ) ) {
auto ret_val = ret - > getReturnValue ( ) ;
if ( result . stack_map . find ( ret_val ) = = result . stack_map . end ( ) & & allocated . find ( ret_val ) = = allocated . end ( ) ) {
result . stack_map [ ret_val ] = stack_offset ;
stack_offset + = 4 ;
allocated . insert ( ret_val ) ;
}
}
}
}
}
// 为 ra 和 s0 预留空间
result . stack_size = stack_offset + 8 ; // ra (4) + s0 (4)
// 按 16 字节对齐
if ( result . stack_size % 16 ! = 0 ) {
result . stack_size + = ( 16 - ( result . stack_size % 16 ) ) ;
}
return result ;
}
void RISCv32CodeGen : : eliminate_phi ( Function * func ) {
// TODO: 实现 p hi 指令 消除
// 占位符:未 实现 P hi 消除
}
std : : map < Instruction * , std : : set < Value * > > RISCv32CodeGen : : liveness_analysis ( Function * func ) {
std : : map < Instruction * , std : : set < Value * > > live_sets ;
// TODO: 实现活跃性分析
// 占位符:未 实现活跃性分析
return live_sets ;
}
std : : map < Value * , std : : set < Value * > > RISCv32CodeGen : : build_interference_graph (
const std : : map < Instruction * , std : : set < Value * > > & live_sets ) {
std : : map < Value * , std : : set < Value * > > graph ;
// TODO: 实现干扰图构建
// 占位符:未 实现干扰图构建
return graph ;
}
RISCv32CodeGen : : RegAllocResult RISCv32CodeGen : : register_allocation ( Function * func ) {
RegAllocResult result ;
// TODO: 实现寄存器分配
return result ;
}
} // namespace sysy