arm64: Refactor Inst::Extend handling
This refactors the handling of Inst::Extend and simplifies the lowering of Bextend and Bmask, which allows the use of SBFX instructions for extensions from 1-bit booleans. Other extensions use aliases of BFM, and the code was changed to reflect that, rather than hard coding bit patterns. Also ImmLogic is now implemented, so another hard coded instruction can be removed. As part of looking at boolean handling, `normalize_boolean_result` was changed to `materialize_boolean_result`, such that it can use either CSET or CSETM. Using CSETM saves an instruction (previously CSET + SUB) for booleans bigger than 1-bit. Copyright (c) 2020, Arm Limited.
This commit is contained in:
@@ -1152,21 +1152,21 @@ pub(crate) fn lower_fcmp_or_ffcmp_to_flags<C: LowerCtx<I = Inst>>(ctx: &mut C, i
|
||||
}
|
||||
}
|
||||
|
||||
/// Convert a 0 / 1 result, such as from a conditional-set instruction, into a 0
|
||||
/// / -1 (all-ones) result as expected for bool operations.
|
||||
pub(crate) fn normalize_bool_result<C: LowerCtx<I = Inst>>(
|
||||
/// Materialize a boolean value into a register from the flags
|
||||
/// (e.g set by a comparison).
|
||||
/// A 0 / -1 (all-ones) result as expected for bool operations.
|
||||
pub(crate) fn materialize_bool_result<C: LowerCtx<I = Inst>>(
|
||||
ctx: &mut C,
|
||||
insn: IRInst,
|
||||
rd: Writable<Reg>,
|
||||
cond: Cond,
|
||||
) {
|
||||
// A boolean is 0 / -1; if output width is > 1, negate.
|
||||
// A boolean is 0 / -1; if output width is > 1 use `csetm`,
|
||||
// otherwise use `cset`.
|
||||
if ty_bits(ctx.output_ty(insn, 0)) > 1 {
|
||||
ctx.emit(Inst::AluRRR {
|
||||
alu_op: ALUOp::Sub64,
|
||||
rd,
|
||||
rn: zero_reg(),
|
||||
rm: rd.to_reg(),
|
||||
});
|
||||
ctx.emit(Inst::CSetm { rd, cond });
|
||||
} else {
|
||||
ctx.emit(Inst::CSet { rd, cond });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user