diff --git a/src/mir/Lowering.cpp b/src/mir/Lowering.cpp index 36ff787..80bd986 100644 --- a/src/mir/Lowering.cpp +++ b/src/mir/Lowering.cpp @@ -7,13 +7,13 @@ #include "ir/IR.h" #include "utils/Log.h" -//#define DEBUG_Lower +#define DEBUG_Lower #ifdef DEBUG_Lower #include #define DEBUG_MSG(msg) std::cerr << "[Lower Debug] " << msg << std::endl #else -#define DEBUG_MSG(msg) +#define DEBUG_MSG(msg) ((void)0) #endif namespace mir { @@ -655,132 +655,166 @@ void LowerInstruction(const ir::Instruction& inst, MachineFunction& function, slots.emplace(&inst, dst_slot); return; } - // ========== GEP 指令(计算数组元素地址)========== case ir::Opcode::GEP: { - auto& gep = static_cast(inst); - - // GEP 返回指针类型,在 ARM64 上指针是 8 字节 - int dst_slot = function.CreateFrameIndex(8); - - // 获取基地址(数组的起始地址) - ir::Value* base = gep.GetBase(); - const auto& indices = gep.GetIndices(); - - // 加载基地址到 x8(使用 64 位寄存器存储地址) - EmitValueToReg(base, PhysReg::X8, slots, block, function); - - if (indices.empty()) { - // 没有索引,直接返回基地址 - block.Append(Opcode::StoreStack, - {Operand::Reg(PhysReg::X8), Operand::FrameIndex(dst_slot)}); - slots.emplace(&inst, dst_slot); - return; - } - - // 获取数组类型信息,计算每个维度的步长 - const ir::Type* baseType = base->GetType().get(); - - // 如果基地址是指针类型,需要解引用获取元素类型 - if (baseType->IsPtrInt32() || baseType->IsPtrFloat() || baseType->IsPtrInt1()) { - // 对于指针类型,第一个索引是偏移量(以元素为单位) - // 例如:int* p; p[1] 的 GEP 中 indices[0] = 1 - if (indices.size() >= 1) { - // 加载索引到 x9 - EmitValueToReg(indices[0], PhysReg::X9, slots, block, function); - - // 乘以元素大小(int/float 是 4 字节) - block.Append(Opcode::MovImm, {Operand::Reg(PhysReg::X10), Operand::Imm(4)}); - block.Append(Opcode::MulRR, {Operand::Reg(PhysReg::X9), - Operand::Reg(PhysReg::X9), - Operand::Reg(PhysReg::X10)}); - - // 地址 = base + index * 4 - block.Append(Opcode::AddRR, {Operand::Reg(PhysReg::X8), - Operand::Reg(PhysReg::X8), - Operand::Reg(PhysReg::X9)}); - } + auto& gep = static_cast(inst); - // 存储计算出的地址 - block.Append(Opcode::StoreStack, - {Operand::Reg(PhysReg::X8), Operand::FrameIndex(dst_slot)}); - slots.emplace(&inst, dst_slot); - return; - } - - // 如果基地址是数组类型,需要处理多维数组 - if (baseType->IsArray()) { - const ir::ArrayType* arrayType = static_cast(baseType); - const std::vector& dims = arrayType->GetDimensions(); + DEBUG_MSG("Processing GEP instruction: " << inst.GetName()); - // 计算每个维度的步长 - std::vector strides(dims.size()); - int stride = 4; // 元素大小(int/float 是 4 字节) - for (int i = dims.size() - 1; i >= 0; --i) { - strides[i] = stride; - stride *= dims[i]; + // GEP 返回指针类型,在 ARM64 上指针是 8 字节 + int dst_slot = function.CreateFrameIndex(8); + + // 获取基地址(数组的起始地址) + ir::Value* base = gep.GetBase(); + const auto& indices = gep.GetIndices(); + + std::string baseName = base->GetName().empty() ? "unnamed" : base->GetName(); + DEBUG_MSG("Base value: " << baseName); + DEBUG_MSG("Number of indices: " << indices.size()); + + // 打印索引值 + for (size_t idx_i = 0; idx_i < indices.size(); ++idx_i) { + if (auto* const_int = dynamic_cast(indices[idx_i])) { + DEBUG_MSG(" Index[" << idx_i << "] = " << const_int->GetValue() << " (constant)"); + } else { + DEBUG_MSG(" Index[" << idx_i << "] = variable"); + } } - // 计算总偏移量 - // 地址 = base + index0 * stride0 + index1 * stride1 + ... - size_t numIndices = indices.size(); + // 加载基地址到 x8 + EmitValueToReg(base, PhysReg::X8, slots, block, function); - // 限制索引数量(不能超过维度数) - if (numIndices > dims.size()) { - numIndices = dims.size(); + if (indices.empty()) { + DEBUG_MSG("No indices, storing base address directly"); + block.Append(Opcode::StoreStack, + {Operand::Reg(PhysReg::X8), Operand::FrameIndex(dst_slot)}); + slots.emplace(&inst, dst_slot); + return; } - // 加载当前地址到 x9 作为偏移量累加器 - block.Append(Opcode::MovImm, {Operand::Reg(PhysReg::X9), Operand::Imm(0)}); + // 获取基地址类型 + const ir::Type* baseType = base->GetType().get(); + DEBUG_MSG("Base type kind: " << static_cast(baseType->GetKind())); - for (size_t i = 0; i < numIndices; ++i) { - // 加载当前索引到 x10 - EmitValueToReg(indices[i], PhysReg::X10, slots, block, function); - - // 乘以步长 - block.Append(Opcode::MovImm, {Operand::Reg(PhysReg::X11), Operand::Imm(strides[i])}); - block.Append(Opcode::MulRR, {Operand::Reg(PhysReg::X10), - Operand::Reg(PhysReg::X10), - Operand::Reg(PhysReg::X11)}); - - // 累加到偏移量 - block.Append(Opcode::AddRR, {Operand::Reg(PhysReg::X9), - Operand::Reg(PhysReg::X9), - Operand::Reg(PhysReg::X10)}); + // 关键修改:对于数组指针类型,第一个索引是多余的,应该跳过 + size_t start_index = 0; + if (baseType->IsPtrInt32() || baseType->IsPtrFloat() || baseType->IsPtrInt1()) { + // 对于指针类型,第一个索引是偏移量,不能跳过 + DEBUG_MSG("Base is pointer type, using all indices for pointer arithmetic"); + start_index = 0; + } else if (baseType->IsArray()) { + // 对于数组类型(非指针),第一个索引是多余的 + // 因为 base 已经是数组本身,不需要再解引用 + DEBUG_MSG("Base is array type, skipping first index (array decay)"); + start_index = 1; } - // 最终地址 = base + offset - block.Append(Opcode::AddRR, {Operand::Reg(PhysReg::X8), - Operand::Reg(PhysReg::X8), - Operand::Reg(PhysReg::X9)}); + // 如果基地址是数组类型,需要处理多维数组 + if (baseType->IsArray()) { + DEBUG_MSG("Base is array type, processing multi-dimensional array"); + const ir::ArrayType* arrayType = static_cast(baseType); + const std::vector& dims = arrayType->GetDimensions(); + + DEBUG_MSG("Array dimensions: "); + for (size_t i = 0; i < dims.size(); ++i) { + DEBUG_MSG(" dim[" << i << "] = " << dims[i]); + } + + // 正确计算每个维度的步长 + std::vector strides(dims.size()); + int element_size = 4; // 元素大小(int/float 是 4 字节) + for (int i = dims.size() - 1; i >= 0; --i) { + if (i == static_cast(dims.size()) - 1) { + strides[i] = element_size; + DEBUG_MSG("strides[" << i << "] = " << strides[i] << " (element size)"); + } else { + strides[i] = strides[i + 1] * dims[i + 1]; + DEBUG_MSG("strides[" << i << "] = " << strides[i+1] << " * " << dims[i+1] + << " = " << strides[i]); + } + } + + // 计算总偏移,跳过第一个索引 + size_t numIndices = indices.size(); + size_t effective_indices = numIndices - start_index; + if (effective_indices > dims.size()) { + DEBUG_MSG("Warning: effective indices (" << effective_indices << ") > dims.size() (" + << dims.size() << "), truncating"); + effective_indices = dims.size(); + } + + DEBUG_MSG("Using " << effective_indices << " effective indices (starting from " << start_index << ")"); + + // 加载当前地址到 x9 作为偏移量累加器 + block.Append(Opcode::MovImm, {Operand::Reg(PhysReg::X9), Operand::Imm(0)}); + + // 用于调试的静态偏移计算 + int debug_offset = 0; + + for (size_t i = 0; i < effective_indices; ++i) { + size_t idx_pos = start_index + i; + int index_value = 0; + if (auto* const_int = dynamic_cast(indices[idx_pos])) { + index_value = const_int->GetValue(); + DEBUG_MSG("Index[" << idx_pos << "] = " << index_value << " (constant)"); + debug_offset += index_value * strides[i]; + DEBUG_MSG(" Contribution = " << index_value << " * " << strides[i] + << " = " << (index_value * strides[i])); + DEBUG_MSG(" Running offset = " << debug_offset); + } else { + DEBUG_MSG("Index[" << idx_pos << "] = variable"); + } + + // 加载当前索引到 x10 + EmitValueToReg(indices[idx_pos], PhysReg::X10, slots, block, function); + + // 乘以步长 + block.Append(Opcode::MovImm, {Operand::Reg(PhysReg::X11), Operand::Imm(strides[i])}); + block.Append(Opcode::MulRR, {Operand::Reg(PhysReg::X10), + Operand::Reg(PhysReg::X10), + Operand::Reg(PhysReg::X11)}); + + // 累加到偏移量 + block.Append(Opcode::AddRR, {Operand::Reg(PhysReg::X9), + Operand::Reg(PhysReg::X9), + Operand::Reg(PhysReg::X10)}); + } + + DEBUG_MSG("Total computed offset = " << debug_offset); + + // 最终地址 = base + offset + block.Append(Opcode::AddRR, {Operand::Reg(PhysReg::X8), + Operand::Reg(PhysReg::X8), + Operand::Reg(PhysReg::X9)}); + + // 存储计算出的地址 + block.Append(Opcode::StoreStack, + {Operand::Reg(PhysReg::X8), Operand::FrameIndex(dst_slot)}); + slots.emplace(&inst, dst_slot); + DEBUG_MSG("Array GEP completed, result stored in slot " << dst_slot); + return; + } + + // 其他情况的处理... + DEBUG_MSG("Base is other type, using simple handling"); + if (indices.size() >= 1) { + EmitValueToReg(indices[0], PhysReg::X9, slots, block, function); + + // 乘以元素大小(默认 4 字节) + block.Append(Opcode::MovImm, {Operand::Reg(PhysReg::X10), Operand::Imm(4)}); + block.Append(Opcode::MulRR, {Operand::Reg(PhysReg::X9), + Operand::Reg(PhysReg::X9), + Operand::Reg(PhysReg::X10)}); + + block.Append(Opcode::AddRR, {Operand::Reg(PhysReg::X8), + Operand::Reg(PhysReg::X8), + Operand::Reg(PhysReg::X9)}); + } - // 存储计算出的地址 block.Append(Opcode::StoreStack, {Operand::Reg(PhysReg::X8), Operand::FrameIndex(dst_slot)}); slots.emplace(&inst, dst_slot); + DEBUG_MSG("Simple GEP completed"); return; - } - - // 其他情况:简单处理 - // 只处理第一个索引 - if (indices.size() >= 1) { - EmitValueToReg(indices[0], PhysReg::X9, slots, block, function); - - // 乘以元素大小(默认 4 字节) - block.Append(Opcode::MovImm, {Operand::Reg(PhysReg::X10), Operand::Imm(4)}); - block.Append(Opcode::MulRR, {Operand::Reg(PhysReg::X9), - Operand::Reg(PhysReg::X9), - Operand::Reg(PhysReg::X10)}); - - block.Append(Opcode::AddRR, {Operand::Reg(PhysReg::X8), - Operand::Reg(PhysReg::X8), - Operand::Reg(PhysReg::X9)}); - } - - // 存储计算出的地址 - block.Append(Opcode::StoreStack, - {Operand::Reg(PhysReg::X8), Operand::FrameIndex(dst_slot)}); - slots.emplace(&inst, dst_slot); - return; } // 处理 Trunc 指令 case ir::Opcode::Trunc: {