A64: Implement URSHR (scalar) and URSRA (scalar)
Now that the utility function is all set up from implementing SRSRA, the unsigned variants can now be trivially implemented by modifying the utility function to perform a logical shift right instead of an arithmetical shift right for the unsigned case.
This commit is contained in:
parent
1e70a589b0
commit
7bce8d8757
2 changed files with 31 additions and 6 deletions
|
@ -480,8 +480,8 @@ INST(SHL_1, "SHL", "01011
|
|||
//INST(FCVTZS_fix_1, "FCVTZS (vector, fixed-point)", "010111110IIIIiii111111nnnnnddddd")
|
||||
INST(USHR_1, "USHR", "011111110IIIIiii000001nnnnnddddd")
|
||||
INST(USRA_1, "USRA", "011111110IIIIiii000101nnnnnddddd")
|
||||
//INST(URSHR_1, "URSHR", "011111110IIIIiii001001nnnnnddddd")
|
||||
//INST(URSRA_1, "URSRA", "011111110IIIIiii001101nnnnnddddd")
|
||||
INST(URSHR_1, "URSHR", "011111110IIIIiii001001nnnnnddddd")
|
||||
INST(URSRA_1, "URSRA", "011111110IIIIiii001101nnnnnddddd")
|
||||
INST(SRI_1, "SRI", "011111110IIIIiii010001nnnnnddddd")
|
||||
INST(SLI_1, "SLI", "011111110IIIIiii010101nnnnnddddd")
|
||||
//INST(SQSHLU_1, "SQSHLU", "011111110IIIIiii011001nnnnnddddd")
|
||||
|
|
|
@ -40,14 +40,21 @@ static void ShiftRight(TranslatorVisitor& v, Imm<4> immh, Imm<3> immb, Vec Vn, V
|
|||
}
|
||||
|
||||
static void RoundingShiftRight(TranslatorVisitor& v, Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd,
|
||||
ShiftExtraBehavior behavior) {
|
||||
ShiftExtraBehavior behavior, Signedness signedness) {
|
||||
const size_t esize = 64;
|
||||
const u8 shift_amount = static_cast<u8>((esize * 2) - concatenate(immh, immb).ZeroExtend());
|
||||
|
||||
const IR::U64 operand = v.V_scalar(esize, Vn);
|
||||
const IR::U64 round_bit = v.ir.LogicalShiftRight(v.ir.LogicalShiftLeft(operand, v.ir.Imm8(64 - shift_amount)), v.ir.Imm8(63));
|
||||
const IR::U64 result = [&] {
|
||||
IR::U64 tmp = v.ir.Add(v.ir.ArithmeticShiftRight(operand, v.ir.Imm8(shift_amount)), round_bit);
|
||||
const IR::U64 shifted = [&]() -> IR::U64 {
|
||||
if (signedness == Signedness::Signed) {
|
||||
return v.ir.ArithmeticShiftRight(operand, v.ir.Imm8(shift_amount));
|
||||
}
|
||||
return v.ir.LogicalShiftRight(operand, v.ir.Imm8(shift_amount));
|
||||
}();
|
||||
|
||||
IR::U64 tmp = v.ir.Add(shifted, round_bit);
|
||||
|
||||
if (behavior == ShiftExtraBehavior::Accumulate) {
|
||||
tmp = v.ir.Add(tmp, v.V_scalar(esize, Vd));
|
||||
|
@ -122,7 +129,7 @@ bool TranslatorVisitor::SRSHR_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
|||
return ReservedValue();
|
||||
}
|
||||
|
||||
RoundingShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::None);
|
||||
RoundingShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::None, Signedness::Signed);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -131,7 +138,7 @@ bool TranslatorVisitor::SRSRA_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
|||
return ReservedValue();
|
||||
}
|
||||
|
||||
RoundingShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::Accumulate);
|
||||
RoundingShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::Accumulate, Signedness::Signed);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -168,6 +175,24 @@ bool TranslatorVisitor::SHL_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::URSHR_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||
if (!immh.Bit<3>()) {
|
||||
return ReservedValue();
|
||||
}
|
||||
|
||||
RoundingShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::None, Signedness::Unsigned);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::URSRA_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||
if (!immh.Bit<3>()) {
|
||||
return ReservedValue();
|
||||
}
|
||||
|
||||
RoundingShiftRight(*this, immh, immb, Vn, Vd, ShiftExtraBehavior::Accumulate, Signedness::Unsigned);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool TranslatorVisitor::USHR_1(Imm<4> immh, Imm<3> immb, Vec Vn, Vec Vd) {
|
||||
if (!immh.Bit<3>()) {
|
||||
return ReservedValue();
|
||||
|
|
Loading…
Reference in a new issue