|
|
|
|
@ -202,21 +202,33 @@ void LowerInstructionToBlock(const ir::Instruction& inst, MachineFunction& funct
|
|
|
|
|
|
|
|
|
|
case ir::Opcode::Store: {
|
|
|
|
|
auto& store = static_cast<const ir::StoreInst&>(inst);
|
|
|
|
|
if (dynamic_cast<const ir::GepInst*>(store.GetPtr())) {
|
|
|
|
|
// 如果指针是 GEP,手动生成地址并 store,避免额外计算
|
|
|
|
|
if (auto* gep = dynamic_cast<const ir::GepInst*>(store.GetPtr())) {
|
|
|
|
|
// 值 -> T2
|
|
|
|
|
EmitValueToReg(store.GetValue(), PhysReg::T2, slots, block);
|
|
|
|
|
EmitValueToReg(store.GetPtr(), PhysReg::T0, slots, block, true);
|
|
|
|
|
block.Append(Opcode::StoreIndirect,
|
|
|
|
|
{Operand::Reg(PhysReg::T2), Operand::Reg(PhysReg::T0)});
|
|
|
|
|
// 基址 -> T0 (for_address=true)
|
|
|
|
|
EmitValueToReg(gep->GetBasePtr(), PhysReg::T0, slots, block, true);
|
|
|
|
|
// 索引直接从栈槽加载(避免递归产生副作用)
|
|
|
|
|
auto idx_it = slots.find(gep->GetIndex());
|
|
|
|
|
if (idx_it != slots.end()) {
|
|
|
|
|
block.Append(Opcode::Load, {Operand::Reg(PhysReg::T1), Operand::FrameIndex(idx_it->second)});
|
|
|
|
|
} else {
|
|
|
|
|
EmitValueToReg(gep->GetIndex(), PhysReg::T1, slots, block);
|
|
|
|
|
}
|
|
|
|
|
// 左移2位 -> 乘4
|
|
|
|
|
block.Append(Opcode::Slli, {Operand::Reg(PhysReg::T1), Operand::Reg(PhysReg::T1), Operand::Imm(2)});
|
|
|
|
|
// 地址相加
|
|
|
|
|
block.Append(Opcode::Add, {Operand::Reg(PhysReg::T0), Operand::Reg(PhysReg::T0), Operand::Reg(PhysReg::T1)});
|
|
|
|
|
// store
|
|
|
|
|
block.Append(Opcode::StoreIndirect, {Operand::Reg(PhysReg::T2), Operand::Reg(PhysReg::T0)});
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (auto* global = dynamic_cast<const ir::GlobalVariable*>(store.GetPtr())) {
|
|
|
|
|
EmitValueToReg(store.GetValue(), PhysReg::T0, slots, block);
|
|
|
|
|
std::string global_name = global->GetName();
|
|
|
|
|
block.Append(Opcode::StoreGlobal,
|
|
|
|
|
{Operand::Reg(PhysReg::T0), Operand::Global(global_name)});
|
|
|
|
|
block.Append(Opcode::StoreGlobal, {Operand::Reg(PhysReg::T0), Operand::Global(global_name)});
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
auto dst = slots.find(store.GetPtr());
|
|
|
|
|
if (dst != slots.end()) {
|
|
|
|
|
EmitValueToReg(store.GetValue(), PhysReg::T0, slots, block);
|
|
|
|
|
@ -228,7 +240,25 @@ void LowerInstructionToBlock(const ir::Instruction& inst, MachineFunction& funct
|
|
|
|
|
|
|
|
|
|
case ir::Opcode::Load: {
|
|
|
|
|
auto& load = static_cast<const ir::LoadInst&>(inst);
|
|
|
|
|
|
|
|
|
|
if (auto* gep = dynamic_cast<const ir::GepInst*>(load.GetPtr())) {
|
|
|
|
|
// 基址 -> T0
|
|
|
|
|
EmitValueToReg(gep->GetBasePtr(), PhysReg::T0, slots, block, true);
|
|
|
|
|
// 索引 -> T1
|
|
|
|
|
auto idx_it = slots.find(gep->GetIndex());
|
|
|
|
|
if (idx_it != slots.end()) {
|
|
|
|
|
block.Append(Opcode::Load, {Operand::Reg(PhysReg::T1), Operand::FrameIndex(idx_it->second)});
|
|
|
|
|
} else {
|
|
|
|
|
EmitValueToReg(gep->GetIndex(), PhysReg::T1, slots, block);
|
|
|
|
|
}
|
|
|
|
|
block.Append(Opcode::Slli, {Operand::Reg(PhysReg::T1), Operand::Reg(PhysReg::T1), Operand::Imm(2)});
|
|
|
|
|
block.Append(Opcode::Add, {Operand::Reg(PhysReg::T0), Operand::Reg(PhysReg::T0), Operand::Reg(PhysReg::T1)});
|
|
|
|
|
// load 到 T0,然后存储到新槽
|
|
|
|
|
block.Append(Opcode::LoadIndirect, {Operand::Reg(PhysReg::T0), Operand::Reg(PhysReg::T0)});
|
|
|
|
|
int dst_slot = function.CreateFrameIndex(4);
|
|
|
|
|
StoreRegToSlot(PhysReg::T0, dst_slot, block, false);
|
|
|
|
|
slots.emplace(&inst, dst_slot);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if (dynamic_cast<const ir::GepInst*>(load.GetPtr())) {
|
|
|
|
|
EmitValueToReg(load.GetPtr(), PhysReg::T0, slots, block, true);
|
|
|
|
|
block.Append(Opcode::LoadIndirect,
|
|
|
|
|
@ -401,26 +431,29 @@ void LowerInstructionToBlock(const ir::Instruction& inst, MachineFunction& funct
|
|
|
|
|
Operand::Reg(PhysReg::T0),
|
|
|
|
|
Operand::Reg(PhysReg::T1)});
|
|
|
|
|
break;
|
|
|
|
|
case ir::ICmpPredicate::SLE:
|
|
|
|
|
block.Append(Opcode::Slt, {Operand::Reg(PhysReg::T1),
|
|
|
|
|
Operand::Reg(PhysReg::T1),
|
|
|
|
|
Operand::Reg(PhysReg::T0)});
|
|
|
|
|
block.Append(Opcode::Xori, {Operand::Reg(PhysReg::T0),
|
|
|
|
|
Operand::Reg(PhysReg::T1),
|
|
|
|
|
Operand::Imm(1)});
|
|
|
|
|
break;
|
|
|
|
|
case ir::ICmpPredicate::SGT:
|
|
|
|
|
block.Append(Opcode::Slt, {Operand::Reg(PhysReg::T0),
|
|
|
|
|
Operand::Reg(PhysReg::T1),
|
|
|
|
|
Operand::Reg(PhysReg::T0)});
|
|
|
|
|
break;
|
|
|
|
|
case ir::ICmpPredicate::SGE:
|
|
|
|
|
block.Append(Opcode::Slt, {Operand::Reg(PhysReg::T1),
|
|
|
|
|
Operand::Reg(PhysReg::T1),
|
|
|
|
|
Operand::Reg(PhysReg::T0)});
|
|
|
|
|
// lhs >= rhs 等价于 !(lhs < rhs)
|
|
|
|
|
block.Append(Opcode::Slt, {Operand::Reg(PhysReg::T0),
|
|
|
|
|
Operand::Reg(PhysReg::T0),
|
|
|
|
|
Operand::Reg(PhysReg::T1)});
|
|
|
|
|
block.Append(Opcode::Xori, {Operand::Reg(PhysReg::T0),
|
|
|
|
|
Operand::Reg(PhysReg::T1),
|
|
|
|
|
Operand::Imm(1)});
|
|
|
|
|
Operand::Reg(PhysReg::T0),
|
|
|
|
|
Operand::Imm(1)});
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case ir::ICmpPredicate::SLE:
|
|
|
|
|
// lhs <= rhs 等价于 !(rhs < lhs)
|
|
|
|
|
block.Append(Opcode::Slt, {Operand::Reg(PhysReg::T0),
|
|
|
|
|
Operand::Reg(PhysReg::T1),
|
|
|
|
|
Operand::Reg(PhysReg::T0)}); // 注意操作数顺序:rhs < lhs
|
|
|
|
|
block.Append(Opcode::Xori, {Operand::Reg(PhysReg::T0),
|
|
|
|
|
Operand::Reg(PhysReg::T0),
|
|
|
|
|
Operand::Imm(1)});
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|