IR: Add masked shift IR instructions

Also use these in the A64 frontend to avoid the need to mask the shift amount.
This commit is contained in:
MerryMage
2020-04-05 17:40:24 +01:00
parent bd88286b21
commit 09d3c77d74
5 changed files with 161 additions and 8 deletions

View File

@@ -185,6 +185,42 @@ U32U64 IREmitter::RotateRight(const U32U64& value_in, const U8& shift_amount) {
}
}
U32U64 IREmitter::LogicalShiftLeftMasked(const U32U64& value_in, const U32U64& shift_amount) {
ASSERT(value_in.GetType() == shift_amount.GetType());
if (value_in.GetType() == Type::U32) {
return Inst<U32>(Opcode::LogicalShiftLeftMasked32, value_in, shift_amount);
} else {
return Inst<U64>(Opcode::LogicalShiftLeftMasked64, value_in, shift_amount);
}
}
U32U64 IREmitter::LogicalShiftRightMasked(const U32U64& value_in, const U32U64& shift_amount) {
ASSERT(value_in.GetType() == shift_amount.GetType());
if (value_in.GetType() == Type::U32) {
return Inst<U32>(Opcode::LogicalShiftRightMasked32, value_in, shift_amount);
} else {
return Inst<U64>(Opcode::LogicalShiftRightMasked64, value_in, shift_amount);
}
}
U32U64 IREmitter::ArithmeticShiftRightMasked(const U32U64& value_in, const U32U64& shift_amount) {
ASSERT(value_in.GetType() == shift_amount.GetType());
if (value_in.GetType() == Type::U32) {
return Inst<U32>(Opcode::ArithmeticShiftRightMasked32, value_in, shift_amount);
} else {
return Inst<U64>(Opcode::ArithmeticShiftRightMasked64, value_in, shift_amount);
}
}
U32U64 IREmitter::RotateRightMasked(const U32U64& value_in, const U32U64& shift_amount) {
ASSERT(value_in.GetType() == shift_amount.GetType());
if (value_in.GetType() == Type::U32) {
return Inst<U32>(Opcode::RotateRightMasked32, value_in, shift_amount);
} else {
return Inst<U64>(Opcode::RotateRightMasked64, value_in, shift_amount);
}
}
ResultAndCarryAndOverflow<U32> IREmitter::AddWithCarry(const U32& a, const U32& b, const U1& carry_in) {
const auto result = Inst<U32>(Opcode::Add32, a, b, carry_in);
const auto carry_out = Inst<U1>(Opcode::GetCarryFromOp, result);