|
|
|
|
@ -15,15 +15,16 @@ namespace {
|
|
|
|
|
|
|
|
|
|
using ValueSlotMap = std::unordered_map<const ir::Value*, int>;
|
|
|
|
|
|
|
|
|
|
// GEP 结果:(base_slot_index, byte_offset, global_symbol)
|
|
|
|
|
// GEP 结果:(base_slot_index, byte_offset, global_symbol, index_value)
|
|
|
|
|
// - base_slot >= 0: 本地数组,base_slot 是栈槽索引
|
|
|
|
|
// - base_slot = -1: 全局数组,global_symbol 是全局变量名
|
|
|
|
|
// - byte_offset >= 0: 常量索引
|
|
|
|
|
// - byte_offset < 0: 变量索引,编码为 -1 - index_slot
|
|
|
|
|
// - byte_offset < 0: 变量索引,index_value 是原始 IR 下标值
|
|
|
|
|
struct GepInfo {
|
|
|
|
|
int base_slot;
|
|
|
|
|
int byte_offset;
|
|
|
|
|
std::string global_symbol;
|
|
|
|
|
const ir::Value* index_value = nullptr;
|
|
|
|
|
};
|
|
|
|
|
using GepMap = std::unordered_map<const ir::Value*, GepInfo>;
|
|
|
|
|
|
|
|
|
|
@ -176,7 +177,7 @@ void LowerInstruction(const ir::Instruction& inst, MachineFunction& function,
|
|
|
|
|
if (auto* const_index = dynamic_cast<const ir::ConstantInt*>(index)) {
|
|
|
|
|
// 常量索引:计算地址并存储
|
|
|
|
|
int byte_offset = const_index->GetValue() * 4;
|
|
|
|
|
geps.emplace(&inst, GepInfo{-1, byte_offset, gv->GetName()});
|
|
|
|
|
geps.emplace(&inst, GepInfo{-1, byte_offset, gv->GetName(), nullptr});
|
|
|
|
|
|
|
|
|
|
if (ptr_slot >= 0) {
|
|
|
|
|
// 计算地址:x9 = &global_array + offset
|
|
|
|
|
@ -188,16 +189,11 @@ void LowerInstruction(const ir::Instruction& inst, MachineFunction& function,
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
// 变量索引
|
|
|
|
|
int index_slot = function.CreateFrameIndex();
|
|
|
|
|
EmitValueToReg(index, PhysReg::W8, slots, block);
|
|
|
|
|
block.Append(Opcode::StoreStack,
|
|
|
|
|
{Operand::Reg(PhysReg::W8), Operand::FrameIndex(index_slot)});
|
|
|
|
|
geps.emplace(&inst, GepInfo{-1, -1 - index_slot, gv->GetName()});
|
|
|
|
|
geps.emplace(&inst, GepInfo{-1, -1, gv->GetName(), index});
|
|
|
|
|
|
|
|
|
|
if (ptr_slot >= 0) {
|
|
|
|
|
// 计算地址:x9 = &global_array + (w10 * 4)
|
|
|
|
|
block.Append(Opcode::LoadStack,
|
|
|
|
|
{Operand::Reg(PhysReg::W10), Operand::FrameIndex(index_slot)});
|
|
|
|
|
EmitValueToReg(index, PhysReg::W10, slots, block);
|
|
|
|
|
EmitLslBy2(PhysReg::W10, block);
|
|
|
|
|
block.Append(Opcode::LoadGlobalAddr,
|
|
|
|
|
{Operand::Reg(PhysReg::X9), Operand::Symbol(gv->GetName())});
|
|
|
|
|
@ -238,17 +234,11 @@ void LowerInstruction(const ir::Instruction& inst, MachineFunction& function,
|
|
|
|
|
{Operand::Reg(PhysReg::X9), Operand::FrameIndex(ptr_slot)});
|
|
|
|
|
} else {
|
|
|
|
|
// 变量索引
|
|
|
|
|
int index_slot = function.CreateFrameIndex();
|
|
|
|
|
EmitValueToReg(index, PhysReg::W8, slots, block);
|
|
|
|
|
block.Append(Opcode::StoreStack,
|
|
|
|
|
{Operand::Reg(PhysReg::W8), Operand::FrameIndex(index_slot)});
|
|
|
|
|
|
|
|
|
|
// x9 = 从栈加载指针
|
|
|
|
|
block.Append(Opcode::LoadStack,
|
|
|
|
|
{Operand::Reg(PhysReg::X9), Operand::FrameIndex(base_it->second)});
|
|
|
|
|
// w10 = index * 4
|
|
|
|
|
block.Append(Opcode::LoadStack,
|
|
|
|
|
{Operand::Reg(PhysReg::W10), Operand::FrameIndex(index_slot)});
|
|
|
|
|
EmitValueToReg(index, PhysReg::W10, slots, block);
|
|
|
|
|
EmitLslBy2(PhysReg::W10, block);
|
|
|
|
|
// x9 = x9 + uxtw(w10)
|
|
|
|
|
block.Append(Opcode::AddRR_UXTW, {Operand::Reg(PhysReg::X9),
|
|
|
|
|
@ -268,7 +258,7 @@ void LowerInstruction(const ir::Instruction& inst, MachineFunction& function,
|
|
|
|
|
// 检查是否是常量索引
|
|
|
|
|
if (auto* const_index = dynamic_cast<const ir::ConstantInt*>(index)) {
|
|
|
|
|
int byte_offset = const_index->GetValue() * 4;
|
|
|
|
|
geps.emplace(&inst, GepInfo{base_it->second, byte_offset, ""});
|
|
|
|
|
geps.emplace(&inst, GepInfo{base_it->second, byte_offset, "", nullptr});
|
|
|
|
|
|
|
|
|
|
if (ptr_slot >= 0) {
|
|
|
|
|
// 计算地址:x9 = &array_base + byte_offset
|
|
|
|
|
@ -280,16 +270,11 @@ void LowerInstruction(const ir::Instruction& inst, MachineFunction& function,
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
// 变量索引
|
|
|
|
|
int index_slot = function.CreateFrameIndex();
|
|
|
|
|
EmitValueToReg(index, PhysReg::W8, slots, block);
|
|
|
|
|
block.Append(Opcode::StoreStack,
|
|
|
|
|
{Operand::Reg(PhysReg::W8), Operand::FrameIndex(index_slot)});
|
|
|
|
|
geps.emplace(&inst, GepInfo{base_it->second, -1 - index_slot, ""});
|
|
|
|
|
geps.emplace(&inst, GepInfo{base_it->second, -1, "", index});
|
|
|
|
|
|
|
|
|
|
if (ptr_slot >= 0) {
|
|
|
|
|
// 计算地址:x9 = x29 + base_offset + (w10 * 4)
|
|
|
|
|
block.Append(Opcode::LoadStack,
|
|
|
|
|
{Operand::Reg(PhysReg::W10), Operand::FrameIndex(index_slot)});
|
|
|
|
|
EmitValueToReg(index, PhysReg::W10, slots, block);
|
|
|
|
|
EmitLslBy2(PhysReg::W10, block);
|
|
|
|
|
block.Append(Opcode::LoadStackAddr,
|
|
|
|
|
{Operand::Reg(PhysReg::X9), Operand::FrameIndex(base_it->second)});
|
|
|
|
|
@ -330,22 +315,12 @@ void LowerInstruction(const ir::Instruction& inst, MachineFunction& function,
|
|
|
|
|
{Operand::Reg(src_reg), Operand::Reg(PhysReg::X9)});
|
|
|
|
|
} else {
|
|
|
|
|
// 变量索引:global_array[var_idx]
|
|
|
|
|
int index_slot = -1 - gep_info.byte_offset;
|
|
|
|
|
// 1. 加载 index(4字节 W 寄存器)
|
|
|
|
|
block.Append(Opcode::LoadStack,
|
|
|
|
|
{Operand::Reg(PhysReg::W10), Operand::FrameIndex(index_slot)});
|
|
|
|
|
// 2. index * 4
|
|
|
|
|
EmitLslBy2(PhysReg::W10, block);
|
|
|
|
|
// 3. 获取全局数组基址
|
|
|
|
|
EmitValueToReg(gep_info.index_value, PhysReg::W10, slots, block);
|
|
|
|
|
block.Append(Opcode::LoadGlobalAddr,
|
|
|
|
|
{Operand::Reg(PhysReg::X9), Operand::Symbol(gep_info.global_symbol)});
|
|
|
|
|
// 4. x9 + w10, uxtw(零扩展 W 寄存器后加到 X 寄存器)
|
|
|
|
|
block.Append(Opcode::AddRR_UXTW, {Operand::Reg(PhysReg::X9),
|
|
|
|
|
Operand::Reg(PhysReg::X9),
|
|
|
|
|
Operand::Reg(PhysReg::W10)});
|
|
|
|
|
// 5. 存储
|
|
|
|
|
block.Append(Opcode::StoreIndirect,
|
|
|
|
|
{Operand::Reg(src_reg), Operand::Reg(PhysReg::X9)});
|
|
|
|
|
block.Append(Opcode::StoreIndirectScaled,
|
|
|
|
|
{Operand::Reg(src_reg), Operand::Reg(PhysReg::X9),
|
|
|
|
|
Operand::Reg(PhysReg::W10)});
|
|
|
|
|
}
|
|
|
|
|
} else if (gep_info.byte_offset >= 0) {
|
|
|
|
|
// 本地数组,常量索引
|
|
|
|
|
@ -355,18 +330,13 @@ void LowerInstruction(const ir::Instruction& inst, MachineFunction& function,
|
|
|
|
|
Operand::Imm(gep_info.byte_offset)});
|
|
|
|
|
} else {
|
|
|
|
|
// 本地数组,变量索引
|
|
|
|
|
int index_slot = -1 - gep_info.byte_offset;
|
|
|
|
|
block.Append(Opcode::LoadStack,
|
|
|
|
|
{Operand::Reg(PhysReg::W10), Operand::FrameIndex(index_slot)});
|
|
|
|
|
EmitLslBy2(PhysReg::W10, block);
|
|
|
|
|
EmitValueToReg(gep_info.index_value, PhysReg::W10, slots, block);
|
|
|
|
|
block.Append(Opcode::LoadStackAddr,
|
|
|
|
|
{Operand::Reg(PhysReg::X9),
|
|
|
|
|
Operand::FrameIndex(gep_info.base_slot)});
|
|
|
|
|
block.Append(Opcode::AddRR_UXTW, {Operand::Reg(PhysReg::X9),
|
|
|
|
|
Operand::Reg(PhysReg::X9),
|
|
|
|
|
Operand::Reg(PhysReg::W10)});
|
|
|
|
|
block.Append(Opcode::StoreIndirect,
|
|
|
|
|
{Operand::Reg(src_reg), Operand::Reg(PhysReg::X9)});
|
|
|
|
|
block.Append(Opcode::StoreIndirectScaled,
|
|
|
|
|
{Operand::Reg(src_reg), Operand::Reg(PhysReg::X9),
|
|
|
|
|
Operand::Reg(PhysReg::W10)});
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
@ -426,17 +396,12 @@ void LowerInstruction(const ir::Instruction& inst, MachineFunction& function,
|
|
|
|
|
{Operand::Reg(value_reg), Operand::Reg(PhysReg::X9)});
|
|
|
|
|
} else {
|
|
|
|
|
// 变量索引
|
|
|
|
|
int index_slot = -1 - gep_info.byte_offset;
|
|
|
|
|
block.Append(Opcode::LoadStack,
|
|
|
|
|
{Operand::Reg(PhysReg::W10), Operand::FrameIndex(index_slot)});
|
|
|
|
|
EmitLslBy2(PhysReg::W10, block);
|
|
|
|
|
EmitValueToReg(gep_info.index_value, PhysReg::W10, slots, block);
|
|
|
|
|
block.Append(Opcode::LoadGlobalAddr,
|
|
|
|
|
{Operand::Reg(PhysReg::X9), Operand::Symbol(gep_info.global_symbol)});
|
|
|
|
|
block.Append(Opcode::AddRR_UXTW, {Operand::Reg(PhysReg::X9),
|
|
|
|
|
Operand::Reg(PhysReg::X9),
|
|
|
|
|
Operand::Reg(PhysReg::W10)});
|
|
|
|
|
block.Append(Opcode::LoadIndirect,
|
|
|
|
|
{Operand::Reg(value_reg), Operand::Reg(PhysReg::X9)});
|
|
|
|
|
block.Append(Opcode::LoadIndirectScaled,
|
|
|
|
|
{Operand::Reg(value_reg), Operand::Reg(PhysReg::X9),
|
|
|
|
|
Operand::Reg(PhysReg::W10)});
|
|
|
|
|
}
|
|
|
|
|
} else if (gep_info.byte_offset >= 0) {
|
|
|
|
|
// 本地数组,常量索引
|
|
|
|
|
@ -446,18 +411,13 @@ void LowerInstruction(const ir::Instruction& inst, MachineFunction& function,
|
|
|
|
|
Operand::Imm(gep_info.byte_offset)});
|
|
|
|
|
} else {
|
|
|
|
|
// 本地数组,变量索引
|
|
|
|
|
int index_slot = -1 - gep_info.byte_offset;
|
|
|
|
|
block.Append(Opcode::LoadStack,
|
|
|
|
|
{Operand::Reg(PhysReg::W10), Operand::FrameIndex(index_slot)});
|
|
|
|
|
EmitLslBy2(PhysReg::W10, block);
|
|
|
|
|
EmitValueToReg(gep_info.index_value, PhysReg::W10, slots, block);
|
|
|
|
|
block.Append(Opcode::LoadStackAddr,
|
|
|
|
|
{Operand::Reg(PhysReg::X9),
|
|
|
|
|
Operand::FrameIndex(gep_info.base_slot)});
|
|
|
|
|
block.Append(Opcode::AddRR_UXTW, {Operand::Reg(PhysReg::X9),
|
|
|
|
|
Operand::Reg(PhysReg::X9),
|
|
|
|
|
Operand::Reg(PhysReg::W10)});
|
|
|
|
|
block.Append(Opcode::LoadIndirect,
|
|
|
|
|
{Operand::Reg(value_reg), Operand::Reg(PhysReg::X9)});
|
|
|
|
|
block.Append(Opcode::LoadIndirectScaled,
|
|
|
|
|
{Operand::Reg(value_reg), Operand::Reg(PhysReg::X9),
|
|
|
|
|
Operand::Reg(PhysReg::W10)});
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
block.Append(Opcode::StoreStack,
|
|
|
|
|
@ -1120,7 +1080,10 @@ std::unique_ptr<MachineModule> LowerToMIR(const ir::Module& module) {
|
|
|
|
|
}
|
|
|
|
|
if (!can_emit) continue; // 跳过无法发射的值
|
|
|
|
|
|
|
|
|
|
PhysReg tmp = phi_info.is_float ? PhysReg::S8 : PhysReg::W8;
|
|
|
|
|
// Phi edge stores may be inserted immediately before fused cbz/cbnz
|
|
|
|
|
// branches, which use w8 as the condition register. Use a different
|
|
|
|
|
// scratch register so edge materialization does not clobber the branch.
|
|
|
|
|
PhysReg tmp = phi_info.is_float ? PhysReg::S10 : PhysReg::W10;
|
|
|
|
|
MachineBasicBlock tmp_block("__phi_tmp__");
|
|
|
|
|
EmitValueToReg(val, tmp, slots, tmp_block);
|
|
|
|
|
tmp_block.Append(Opcode::StoreStack,
|
|
|
|
|
|