|
|
|
|
@ -473,101 +473,7 @@ namespace mir
|
|
|
|
|
value_vregs[value] = dst;
|
|
|
|
|
return dst;
|
|
|
|
|
}
|
|
|
|
|
if (val > 0 && (val & (val - 1)) == 0)
|
|
|
|
|
{
|
|
|
|
|
int shift = 0;
|
|
|
|
|
int tmp = val;
|
|
|
|
|
while (tmp > 1)
|
|
|
|
|
{
|
|
|
|
|
tmp >>= 1;
|
|
|
|
|
++shift;
|
|
|
|
|
}
|
|
|
|
|
int bias = (1 << shift) - 1;
|
|
|
|
|
int biased = function.CreateVReg(VRegClass::Int);
|
|
|
|
|
if (bias <= 4095)
|
|
|
|
|
{
|
|
|
|
|
block.Append(Opcode::AddRR,
|
|
|
|
|
{Operand::VReg(biased, VRegClass::Int),
|
|
|
|
|
Operand::VReg(lhs, VRegClass::Int),
|
|
|
|
|
Operand::Imm(bias)});
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
int bias_reg = function.CreateVReg(VRegClass::Int);
|
|
|
|
|
block.Append(Opcode::MovImm,
|
|
|
|
|
{Operand::VReg(bias_reg, VRegClass::Int),
|
|
|
|
|
Operand::Imm(bias)}).SetRematerializable(true).SetRematImm(bias);
|
|
|
|
|
block.Append(Opcode::AddRR,
|
|
|
|
|
{Operand::VReg(biased, VRegClass::Int),
|
|
|
|
|
Operand::VReg(lhs, VRegClass::Int),
|
|
|
|
|
Operand::VReg(bias_reg, VRegClass::Int)});
|
|
|
|
|
}
|
|
|
|
|
block.Append(Opcode::CmpImm,
|
|
|
|
|
{Operand::VReg(lhs, VRegClass::Int),
|
|
|
|
|
Operand::Imm(0)});
|
|
|
|
|
int selected = function.CreateVReg(VRegClass::Int);
|
|
|
|
|
block.Append(Opcode::Csel,
|
|
|
|
|
{Operand::VReg(selected, VRegClass::Int),
|
|
|
|
|
Operand::VReg(biased, VRegClass::Int),
|
|
|
|
|
Operand::VReg(lhs, VRegClass::Int),
|
|
|
|
|
Operand::Imm(static_cast<int>(CondCode::LT))});
|
|
|
|
|
block.Append(Opcode::AsrRR,
|
|
|
|
|
{Operand::VReg(dst, VRegClass::Int),
|
|
|
|
|
Operand::VReg(selected, VRegClass::Int),
|
|
|
|
|
Operand::Imm(shift)});
|
|
|
|
|
value_vregs[value] = dst;
|
|
|
|
|
return dst;
|
|
|
|
|
}
|
|
|
|
|
if (val < 0 && (-val & (-val - 1)) == 0 && val != -1)
|
|
|
|
|
{
|
|
|
|
|
int abs_val = -val;
|
|
|
|
|
int shift = 0;
|
|
|
|
|
int tmp = abs_val;
|
|
|
|
|
while (tmp > 1)
|
|
|
|
|
{
|
|
|
|
|
tmp >>= 1;
|
|
|
|
|
++shift;
|
|
|
|
|
}
|
|
|
|
|
int bias = (1 << shift) - 1;
|
|
|
|
|
int biased = function.CreateVReg(VRegClass::Int);
|
|
|
|
|
if (bias <= 4095)
|
|
|
|
|
{
|
|
|
|
|
block.Append(Opcode::AddRR,
|
|
|
|
|
{Operand::VReg(biased, VRegClass::Int),
|
|
|
|
|
Operand::VReg(lhs, VRegClass::Int),
|
|
|
|
|
Operand::Imm(bias)});
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
int bias_reg = function.CreateVReg(VRegClass::Int);
|
|
|
|
|
block.Append(Opcode::MovImm,
|
|
|
|
|
{Operand::VReg(bias_reg, VRegClass::Int),
|
|
|
|
|
Operand::Imm(bias)}).SetRematerializable(true).SetRematImm(bias);
|
|
|
|
|
block.Append(Opcode::AddRR,
|
|
|
|
|
{Operand::VReg(biased, VRegClass::Int),
|
|
|
|
|
Operand::VReg(lhs, VRegClass::Int),
|
|
|
|
|
Operand::VReg(bias_reg, VRegClass::Int)});
|
|
|
|
|
}
|
|
|
|
|
block.Append(Opcode::CmpImm,
|
|
|
|
|
{Operand::VReg(lhs, VRegClass::Int),
|
|
|
|
|
Operand::Imm(0)});
|
|
|
|
|
int selected = function.CreateVReg(VRegClass::Int);
|
|
|
|
|
block.Append(Opcode::Csel,
|
|
|
|
|
{Operand::VReg(selected, VRegClass::Int),
|
|
|
|
|
Operand::VReg(biased, VRegClass::Int),
|
|
|
|
|
Operand::VReg(lhs, VRegClass::Int),
|
|
|
|
|
Operand::Imm(static_cast<int>(CondCode::LT))});
|
|
|
|
|
int pos_q = function.CreateVReg(VRegClass::Int);
|
|
|
|
|
block.Append(Opcode::AsrRR,
|
|
|
|
|
{Operand::VReg(pos_q, VRegClass::Int),
|
|
|
|
|
Operand::VReg(selected, VRegClass::Int),
|
|
|
|
|
Operand::Imm(shift)});
|
|
|
|
|
block.Append(Opcode::NegRR,
|
|
|
|
|
{Operand::VReg(dst, VRegClass::Int),
|
|
|
|
|
Operand::VReg(pos_q, VRegClass::Int)});
|
|
|
|
|
value_vregs[value] = dst;
|
|
|
|
|
return dst;
|
|
|
|
|
}
|
|
|
|
|
// 2的幂次除法(含正负)改用 sdiv,比移位序列更短
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@ -577,121 +483,16 @@ namespace mir
|
|
|
|
|
if (rhs_const)
|
|
|
|
|
{
|
|
|
|
|
int val = rhs_const->GetValue();
|
|
|
|
|
if (val > 0 && (val & (val - 1)) == 0)
|
|
|
|
|
// x % 1 == 0, x % -1 == 0
|
|
|
|
|
if (val == 1 || val == -1)
|
|
|
|
|
{
|
|
|
|
|
int bias = val - 1;
|
|
|
|
|
int biased = function.CreateVReg(VRegClass::Int);
|
|
|
|
|
if (bias <= 4095)
|
|
|
|
|
{
|
|
|
|
|
block.Append(Opcode::AddRR,
|
|
|
|
|
{Operand::VReg(biased, VRegClass::Int),
|
|
|
|
|
Operand::VReg(lhs, VRegClass::Int),
|
|
|
|
|
Operand::Imm(bias)});
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
int bias_reg = function.CreateVReg(VRegClass::Int);
|
|
|
|
|
block.Append(Opcode::MovImm,
|
|
|
|
|
{Operand::VReg(bias_reg, VRegClass::Int),
|
|
|
|
|
Operand::Imm(bias)}).SetRematerializable(true).SetRematImm(bias);
|
|
|
|
|
block.Append(Opcode::AddRR,
|
|
|
|
|
{Operand::VReg(biased, VRegClass::Int),
|
|
|
|
|
Operand::VReg(lhs, VRegClass::Int),
|
|
|
|
|
Operand::VReg(bias_reg, VRegClass::Int)});
|
|
|
|
|
}
|
|
|
|
|
int shift = 0;
|
|
|
|
|
int tmp = val;
|
|
|
|
|
while (tmp > 1)
|
|
|
|
|
{
|
|
|
|
|
tmp >>= 1;
|
|
|
|
|
++shift;
|
|
|
|
|
}
|
|
|
|
|
block.Append(Opcode::CmpImm,
|
|
|
|
|
{Operand::VReg(lhs, VRegClass::Int),
|
|
|
|
|
Operand::Imm(0)});
|
|
|
|
|
int selected = function.CreateVReg(VRegClass::Int);
|
|
|
|
|
block.Append(Opcode::Csel,
|
|
|
|
|
{Operand::VReg(selected, VRegClass::Int),
|
|
|
|
|
Operand::VReg(biased, VRegClass::Int),
|
|
|
|
|
Operand::VReg(lhs, VRegClass::Int),
|
|
|
|
|
Operand::Imm(static_cast<int>(CondCode::LT))});
|
|
|
|
|
int q_dst = function.CreateVReg(VRegClass::Int);
|
|
|
|
|
block.Append(Opcode::AsrRR,
|
|
|
|
|
{Operand::VReg(q_dst, VRegClass::Int),
|
|
|
|
|
Operand::VReg(selected, VRegClass::Int),
|
|
|
|
|
Operand::Imm(shift)});
|
|
|
|
|
int d_reg = function.CreateVReg(VRegClass::Int);
|
|
|
|
|
block.Append(Opcode::MovImm,
|
|
|
|
|
{Operand::VReg(d_reg, VRegClass::Int),
|
|
|
|
|
Operand::Imm(val)}).SetRematerializable(true).SetRematImm(val);
|
|
|
|
|
block.Append(Opcode::Msub,
|
|
|
|
|
{Operand::VReg(dst, VRegClass::Int),
|
|
|
|
|
Operand::VReg(q_dst, VRegClass::Int),
|
|
|
|
|
Operand::VReg(d_reg, VRegClass::Int),
|
|
|
|
|
Operand::VReg(lhs, VRegClass::Int)});
|
|
|
|
|
value_vregs[value] = dst;
|
|
|
|
|
return dst;
|
|
|
|
|
}
|
|
|
|
|
if (val < 0 && (-val & (-val - 1)) == 0 && val != -1)
|
|
|
|
|
{
|
|
|
|
|
int abs_val = -val;
|
|
|
|
|
int bias = abs_val - 1;
|
|
|
|
|
int biased = function.CreateVReg(VRegClass::Int);
|
|
|
|
|
if (bias <= 4095)
|
|
|
|
|
{
|
|
|
|
|
block.Append(Opcode::AddRR,
|
|
|
|
|
{Operand::VReg(biased, VRegClass::Int),
|
|
|
|
|
Operand::VReg(lhs, VRegClass::Int),
|
|
|
|
|
Operand::Imm(bias)});
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
int bias_reg = function.CreateVReg(VRegClass::Int);
|
|
|
|
|
block.Append(Opcode::MovImm,
|
|
|
|
|
{Operand::VReg(bias_reg, VRegClass::Int),
|
|
|
|
|
Operand::Imm(bias)}).SetRematerializable(true).SetRematImm(bias);
|
|
|
|
|
block.Append(Opcode::AddRR,
|
|
|
|
|
{Operand::VReg(biased, VRegClass::Int),
|
|
|
|
|
Operand::VReg(lhs, VRegClass::Int),
|
|
|
|
|
Operand::VReg(bias_reg, VRegClass::Int)});
|
|
|
|
|
}
|
|
|
|
|
int shift = 0;
|
|
|
|
|
int tmp = abs_val;
|
|
|
|
|
while (tmp > 1)
|
|
|
|
|
{
|
|
|
|
|
tmp >>= 1;
|
|
|
|
|
++shift;
|
|
|
|
|
}
|
|
|
|
|
block.Append(Opcode::CmpImm,
|
|
|
|
|
{Operand::VReg(lhs, VRegClass::Int),
|
|
|
|
|
Operand::Imm(0)});
|
|
|
|
|
int selected = function.CreateVReg(VRegClass::Int);
|
|
|
|
|
block.Append(Opcode::Csel,
|
|
|
|
|
{Operand::VReg(selected, VRegClass::Int),
|
|
|
|
|
Operand::VReg(biased, VRegClass::Int),
|
|
|
|
|
Operand::VReg(lhs, VRegClass::Int),
|
|
|
|
|
Operand::Imm(static_cast<int>(CondCode::LT))});
|
|
|
|
|
int asr_result = function.CreateVReg(VRegClass::Int);
|
|
|
|
|
block.Append(Opcode::AsrRR,
|
|
|
|
|
{Operand::VReg(asr_result, VRegClass::Int),
|
|
|
|
|
Operand::VReg(selected, VRegClass::Int),
|
|
|
|
|
Operand::Imm(shift)});
|
|
|
|
|
int q_dst = function.CreateVReg(VRegClass::Int);
|
|
|
|
|
block.Append(Opcode::NegRR,
|
|
|
|
|
{Operand::VReg(q_dst, VRegClass::Int),
|
|
|
|
|
Operand::VReg(asr_result, VRegClass::Int)});
|
|
|
|
|
int d_reg = function.CreateVReg(VRegClass::Int);
|
|
|
|
|
block.Append(Opcode::MovImm,
|
|
|
|
|
{Operand::VReg(d_reg, VRegClass::Int),
|
|
|
|
|
Operand::Imm(val)}).SetRematerializable(true).SetRematImm(val);
|
|
|
|
|
block.Append(Opcode::Msub,
|
|
|
|
|
{Operand::VReg(dst, VRegClass::Int),
|
|
|
|
|
Operand::VReg(q_dst, VRegClass::Int),
|
|
|
|
|
Operand::VReg(d_reg, VRegClass::Int),
|
|
|
|
|
Operand::VReg(lhs, VRegClass::Int)});
|
|
|
|
|
Operand::Imm(0)}).SetRematerializable(true).SetRematImm(0);
|
|
|
|
|
value_vregs[value] = dst;
|
|
|
|
|
return dst;
|
|
|
|
|
}
|
|
|
|
|
// 2的幂次取模(含正负)改用 ModRR(sdiv+msub),比移位序列更短
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|