|
|
|
|
@ -1390,28 +1390,73 @@ namespace mir
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int addr = EmitPtrValue(load.GetPtr(), function, value_vregs,
|
|
|
|
|
scalar_slots, array_slots, block);
|
|
|
|
|
if (is_ptr)
|
|
|
|
|
{
|
|
|
|
|
int vreg = function.CreateVReg(VRegClass::Ptr);
|
|
|
|
|
block.Append(Opcode::LoadMem,
|
|
|
|
|
{Operand::VReg(vreg, VRegClass::Ptr), Operand::VReg(addr, VRegClass::Ptr)});
|
|
|
|
|
value_vregs[&load] = vreg;
|
|
|
|
|
}
|
|
|
|
|
else if (is_float)
|
|
|
|
|
// 缩放寻址:GEP + Load → ldr [base, idx, uxtw #2]
|
|
|
|
|
bool scaled_load = false;
|
|
|
|
|
if (auto *gep = dynamic_cast<const ir::GetElementPtrInst *>(load.GetPtr()))
|
|
|
|
|
{
|
|
|
|
|
int vreg = function.CreateVReg(VRegClass::Float);
|
|
|
|
|
block.Append(Opcode::LoadMem,
|
|
|
|
|
{Operand::VReg(vreg, VRegClass::Float), Operand::VReg(addr, VRegClass::Ptr)});
|
|
|
|
|
value_vregs[&load] = vreg;
|
|
|
|
|
int idx_imm = 0;
|
|
|
|
|
if (!TryGetConstantInt(gep->GetIndex(), idx_imm))
|
|
|
|
|
{
|
|
|
|
|
scaled_load = true;
|
|
|
|
|
int base_addr = EmitPtrValue(gep->GetBasePtr(), function, value_vregs,
|
|
|
|
|
scalar_slots, array_slots, block);
|
|
|
|
|
int idx_vreg = EmitIntValue(gep->GetIndex(), function, value_vregs,
|
|
|
|
|
scalar_slots, array_slots, block);
|
|
|
|
|
if (is_ptr)
|
|
|
|
|
{
|
|
|
|
|
int vreg = function.CreateVReg(VRegClass::Ptr);
|
|
|
|
|
block.Append(Opcode::LoadMem,
|
|
|
|
|
{Operand::VReg(vreg, VRegClass::Ptr),
|
|
|
|
|
Operand::VReg(base_addr, VRegClass::Ptr),
|
|
|
|
|
Operand::VReg(idx_vreg, VRegClass::Int)});
|
|
|
|
|
value_vregs[&load] = vreg;
|
|
|
|
|
}
|
|
|
|
|
else if (is_float)
|
|
|
|
|
{
|
|
|
|
|
int vreg = function.CreateVReg(VRegClass::Float);
|
|
|
|
|
block.Append(Opcode::LoadMem,
|
|
|
|
|
{Operand::VReg(vreg, VRegClass::Float),
|
|
|
|
|
Operand::VReg(base_addr, VRegClass::Ptr),
|
|
|
|
|
Operand::VReg(idx_vreg, VRegClass::Int)});
|
|
|
|
|
value_vregs[&load] = vreg;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
int vreg = function.CreateVReg(VRegClass::Int);
|
|
|
|
|
block.Append(Opcode::LoadMem,
|
|
|
|
|
{Operand::VReg(vreg, VRegClass::Int),
|
|
|
|
|
Operand::VReg(base_addr, VRegClass::Ptr),
|
|
|
|
|
Operand::VReg(idx_vreg, VRegClass::Int)});
|
|
|
|
|
value_vregs[&load] = vreg;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
|
|
|
|
|
if (!scaled_load)
|
|
|
|
|
{
|
|
|
|
|
int vreg = function.CreateVReg(VRegClass::Int);
|
|
|
|
|
block.Append(Opcode::LoadMem,
|
|
|
|
|
{Operand::VReg(vreg, VRegClass::Int), Operand::VReg(addr, VRegClass::Ptr)});
|
|
|
|
|
value_vregs[&load] = vreg;
|
|
|
|
|
int addr = EmitPtrValue(load.GetPtr(), function, value_vregs,
|
|
|
|
|
scalar_slots, array_slots, block);
|
|
|
|
|
if (is_ptr)
|
|
|
|
|
{
|
|
|
|
|
int vreg = function.CreateVReg(VRegClass::Ptr);
|
|
|
|
|
block.Append(Opcode::LoadMem,
|
|
|
|
|
{Operand::VReg(vreg, VRegClass::Ptr), Operand::VReg(addr, VRegClass::Ptr)});
|
|
|
|
|
value_vregs[&load] = vreg;
|
|
|
|
|
}
|
|
|
|
|
else if (is_float)
|
|
|
|
|
{
|
|
|
|
|
int vreg = function.CreateVReg(VRegClass::Float);
|
|
|
|
|
block.Append(Opcode::LoadMem,
|
|
|
|
|
{Operand::VReg(vreg, VRegClass::Float), Operand::VReg(addr, VRegClass::Ptr)});
|
|
|
|
|
value_vregs[&load] = vreg;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
int vreg = function.CreateVReg(VRegClass::Int);
|
|
|
|
|
block.Append(Opcode::LoadMem,
|
|
|
|
|
{Operand::VReg(vreg, VRegClass::Int), Operand::VReg(addr, VRegClass::Ptr)});
|
|
|
|
|
value_vregs[&load] = vreg;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|