|
|
|
|
@ -724,6 +724,26 @@ namespace mir
|
|
|
|
|
return vreg;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 缩放寻址:GEP + Load → ldr [base, idx, uxtw #2]
|
|
|
|
|
if (auto *gep = dynamic_cast<const ir::GetElementPtrInst *>(load->GetPtr()))
|
|
|
|
|
{
|
|
|
|
|
int idx_imm = 0;
|
|
|
|
|
if (!TryGetConstantInt(gep->GetIndex(), idx_imm))
|
|
|
|
|
{
|
|
|
|
|
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);
|
|
|
|
|
int data_vreg = function.CreateVReg(VRegClass::Int);
|
|
|
|
|
block.Append(Opcode::LoadMem,
|
|
|
|
|
{Operand::VReg(data_vreg, VRegClass::Int),
|
|
|
|
|
Operand::VReg(base_addr, VRegClass::Ptr),
|
|
|
|
|
Operand::VReg(idx_vreg, VRegClass::Int)});
|
|
|
|
|
value_vregs[value] = data_vreg;
|
|
|
|
|
return data_vreg;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int addr = EmitPtrValue(load->GetPtr(), function, value_vregs,
|
|
|
|
|
scalar_slots, array_slots, block);
|
|
|
|
|
int vreg = function.CreateVReg(VRegClass::Int);
|
|
|
|
|
@ -1449,27 +1469,71 @@ namespace mir
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int addr = EmitPtrValue(store.GetPtr(), function, value_vregs,
|
|
|
|
|
scalar_slots, array_slots, block);
|
|
|
|
|
if (value_is_ptr)
|
|
|
|
|
// 缩放寻址:GEP + Store → str [base, idx, uxtw #2]
|
|
|
|
|
bool scaled_store = false;
|
|
|
|
|
if (auto *gep = dynamic_cast<const ir::GetElementPtrInst *>(store.GetPtr()))
|
|
|
|
|
{
|
|
|
|
|
int val = EmitPtrValue(store.GetValue(), function, value_vregs,
|
|
|
|
|
scalar_slots, array_slots, block);
|
|
|
|
|
block.Append(Opcode::StoreMem,
|
|
|
|
|
{Operand::VReg(val, VRegClass::Ptr), Operand::VReg(addr, VRegClass::Ptr)});
|
|
|
|
|
}
|
|
|
|
|
else if (value_is_float)
|
|
|
|
|
{
|
|
|
|
|
int val = EmitFloatValue(store.GetValue(), function, value_vregs, block);
|
|
|
|
|
block.Append(Opcode::StoreMem,
|
|
|
|
|
{Operand::VReg(val, VRegClass::Float), Operand::VReg(addr, VRegClass::Ptr)});
|
|
|
|
|
int idx_imm = 0;
|
|
|
|
|
if (!TryGetConstantInt(gep->GetIndex(), idx_imm))
|
|
|
|
|
{
|
|
|
|
|
scaled_store = 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 (value_is_ptr)
|
|
|
|
|
{
|
|
|
|
|
int val = EmitPtrValue(store.GetValue(), function, value_vregs,
|
|
|
|
|
scalar_slots, array_slots, block);
|
|
|
|
|
block.Append(Opcode::StoreMem,
|
|
|
|
|
{Operand::VReg(val, VRegClass::Ptr),
|
|
|
|
|
Operand::VReg(base_addr, VRegClass::Ptr),
|
|
|
|
|
Operand::VReg(idx_vreg, VRegClass::Int)});
|
|
|
|
|
}
|
|
|
|
|
else if (value_is_float)
|
|
|
|
|
{
|
|
|
|
|
int val = EmitFloatValue(store.GetValue(), function, value_vregs, block);
|
|
|
|
|
block.Append(Opcode::StoreMem,
|
|
|
|
|
{Operand::VReg(val, VRegClass::Float),
|
|
|
|
|
Operand::VReg(base_addr, VRegClass::Ptr),
|
|
|
|
|
Operand::VReg(idx_vreg, VRegClass::Int)});
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
int val = EmitIntValue(store.GetValue(), function, value_vregs,
|
|
|
|
|
scalar_slots, array_slots, block);
|
|
|
|
|
block.Append(Opcode::StoreMem,
|
|
|
|
|
{Operand::VReg(val, VRegClass::Int),
|
|
|
|
|
Operand::VReg(base_addr, VRegClass::Ptr),
|
|
|
|
|
Operand::VReg(idx_vreg, VRegClass::Int)});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
|
|
|
|
|
if (!scaled_store)
|
|
|
|
|
{
|
|
|
|
|
int val = EmitIntValue(store.GetValue(), function, value_vregs,
|
|
|
|
|
scalar_slots, array_slots, block);
|
|
|
|
|
block.Append(Opcode::StoreMem,
|
|
|
|
|
{Operand::VReg(val, VRegClass::Int), Operand::VReg(addr, VRegClass::Ptr)});
|
|
|
|
|
int addr = EmitPtrValue(store.GetPtr(), function, value_vregs,
|
|
|
|
|
scalar_slots, array_slots, block);
|
|
|
|
|
if (value_is_ptr)
|
|
|
|
|
{
|
|
|
|
|
int val = EmitPtrValue(store.GetValue(), function, value_vregs,
|
|
|
|
|
scalar_slots, array_slots, block);
|
|
|
|
|
block.Append(Opcode::StoreMem,
|
|
|
|
|
{Operand::VReg(val, VRegClass::Ptr), Operand::VReg(addr, VRegClass::Ptr)});
|
|
|
|
|
}
|
|
|
|
|
else if (value_is_float)
|
|
|
|
|
{
|
|
|
|
|
int val = EmitFloatValue(store.GetValue(), function, value_vregs, block);
|
|
|
|
|
block.Append(Opcode::StoreMem,
|
|
|
|
|
{Operand::VReg(val, VRegClass::Float), Operand::VReg(addr, VRegClass::Ptr)});
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
int val = EmitIntValue(store.GetValue(), function, value_vregs,
|
|
|
|
|
scalar_slots, array_slots, block);
|
|
|
|
|
block.Append(Opcode::StoreMem,
|
|
|
|
|
{Operand::VReg(val, VRegClass::Int), Operand::VReg(addr, VRegClass::Ptr)});
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|