/// Lower an instruction input to a reg or reg/shift, or reg/extend operand.
/// This does not actually codegen the source instruction; it just uses the
/// vreg into which the source instruction will generate its value.
///
/// See note on `input_to_rs` for a description of `narrow_mode`.
Lower an instruction input to a reg or reg/shift, or reg/extend operand.
This does not actually codegen the source instruction; it just uses the
vreg into which the source instruction will generate its value.

See note on `input_to_rs` for a description of `narrow_mode`.
Lower an instruction input to a reg or reg / shift or reg / extend operand . This does not actually codegen the source instruction ; it just uses the vreg into which the source instruction will generate its value . See note on ` input_to_rs ` for a description of ` narrow_mode ` .
fn input_to_rse<C: LowerCtx<Inst>>(
    ctx: &mut C,
    input: InsnInput,
    narrow_mode: NarrowValueMode,
) -> ResultRSE {
    if let InsnInputSource::Output(out) = input_source(ctx, input) {
        let insn = out.insn;
        assert!(out.output <= ctx.num_outputs(insn));
        let op = ctx.data(insn).opcode();
        let out_ty = ctx.output_ty(insn, out.output);
        let out_bits = ty_bits(out_ty);
        // If `out_ty` is smaller than 32 bits and we need to zero- or sign-extend,
        // then get the result into a register and return an Extend-mode operand on
        // that register.
        if narrow_mode != NarrowValueMode::None
            && ((narrow_mode.is_32bit() && out_bits < 32)
                || (!narrow_mode.is_32bit() && out_bits < 64))
        {
            let reg = output_to_reg(ctx, out);
            let extendop = match (narrow_mode, out_bits) {
                (NarrowValueMode::SignExtend32, 1) | (NarrowValueMode::SignExtend64, 1) => {
                    ExtendOp::SXTB
                }
                (NarrowValueMode::ZeroExtend32, 1) | (NarrowValueMode::ZeroExtend64, 1) => {
                    ExtendOp::UXTB
                }
                (NarrowValueMode::SignExtend32, 8) | (NarrowValueMode::SignExtend64, 8) => {
                    ExtendOp::SXTB
                }
                (NarrowValueMode::ZeroExtend32, 8) | (NarrowValueMode::ZeroExtend64, 8) => {
                    ExtendOp::UXTB
                }
                (NarrowValueMode::SignExtend32, 16) | (NarrowValueMode::SignExtend64, 16) => {
                    ExtendOp::SXTH
                }
                (NarrowValueMode::ZeroExtend32, 16) | (NarrowValueMode::ZeroExtend64, 16) => {
                    ExtendOp::UXTH
                }
                (NarrowValueMode::SignExtend64, 32) => ExtendOp::SXTW,
                (NarrowValueMode::ZeroExtend64, 32) => ExtendOp::UXTW,
                _ => unreachable!(),
            };
            return ResultRSE::RegExtend(reg.to_reg(), extendop);
        }
        // Is this a zero-extend or sign-extend and can we handle that with a register-mode operator?
        if op == Opcode::Uextend || op == Opcode::Sextend {
            assert!(out_bits == 32 || out_bits == 64);
            let sign_extend = op == Opcode::Sextend;
            let extendee = get_input(ctx, out, 0);
            let inner_ty = ctx.input_ty(extendee.insn, extendee.input);
            let inner_bits = ty_bits(inner_ty);
            assert!(inner_bits < out_bits);
            let extendop = match (sign_extend, inner_bits) {
                (true, 1) => ExtendOp::SXTB,
                (false, 1) => ExtendOp::UXTB,
                (true, 8) => ExtendOp::SXTB,
                (false, 8) => ExtendOp::UXTB,
                (true, 16) => ExtendOp::SXTH,
                (false, 16) => ExtendOp::UXTH,
                (true, 32) => ExtendOp::SXTW,
                (false, 32) => ExtendOp::UXTW,
                _ => unreachable!(),
            };
            let reg = input_to_reg(ctx, extendee, NarrowValueMode::None);
            ctx.merged(insn);
            return ResultRSE::RegExtend(reg, extendop);
        }
    }
    ResultRSE::from_rs(input_to_rs(ctx, input, narrow_mode))
}
fn input_to_rse < C : LowerCtx < Inst > > ( ctx : & mut C , input : InsnInput , narrow_mode : NarrowValueMode , ) -> ResultRSE { if let InsnInputSource :: Output ( out ) = input_source ( ctx , input ) { let insn = out . insn ; assert ! ( out output ctx num_outputs ( insn ) ) ; let op = ctx . data ( insn ) . opcode ( ) ; let out_ty = ctx . output_ty ( insn , out . output ) ; let out_bits = ty_bits ( out_ty ) ; // If `out_ty` is smaller than 32 bits and we need to zero- or sign-extend, // then get the result into a register and return an Extend-mode operand on // that register. if narrow_mode != NarrowValueMode :: None && ( ( narrow_mode . is_32bit ( ) && out_bits < 32 ) || ( ! narrow_mode . is_32bit ( ) && out_bits < 64 ) ) { let reg = output_to_reg ( ctx , out ) ; let extendop = match ( narrow_mode , out_bits ) { ( NarrowValueMode :: SignExtend32 , 1 ) | ( NarrowValueMode :: SignExtend64 , 1 ) => { ExtendOp :: SXTB } ( NarrowValueMode :: ZeroExtend32 , 1 ) | ( NarrowValueMode :: ZeroExtend64 , 1 ) => { ExtendOp :: UXTB } ( NarrowValueMode :: SignExtend32 , 8 ) | ( NarrowValueMode :: SignExtend64 , 8 ) => { ExtendOp :: SXTB } ( NarrowValueMode :: ZeroExtend32 , 8 ) | ( NarrowValueMode :: ZeroExtend64 , 8 ) => { ExtendOp :: UXTB } ( NarrowValueMode :: SignExtend32 , 16 ) | ( NarrowValueMode :: SignExtend64 , 16 ) => { ExtendOp :: SXTH } ( NarrowValueMode :: ZeroExtend32 , 16 ) | ( NarrowValueMode :: ZeroExtend64 , 16 ) => { ExtendOp :: UXTH } ( NarrowValueMode :: SignExtend64 , 32 ) => ExtendOp :: SXTW , ( NarrowValueMode :: ZeroExtend64 , 32 ) => ExtendOp :: UXTW , _ => unreachable ! ( ) , } ; return ResultRSE :: RegExtend ( reg . to_reg ( ) , extendop ) ; } // Is this a zero-extend or sign-extend and can we handle that with a register-mode operator? if op == Opcode :: Uextend || op == Opcode :: Sextend { assert ! ( out_bits 32 out_bits 64 ) ; let sign_extend = op == Opcode :: Sextend ; let extendee = get_input ( ctx , out , 0 ) ; let inner_ty = ctx . input_ty ( extendee . insn , extendee . input ) ; let inner_bits = ty_bits ( inner_ty ) ; assert ! ( inner_bits out_bits ) ; let extendop = match ( sign_extend , inner_bits ) { ( true , 1 ) => ExtendOp :: SXTB , ( false , 1 ) => ExtendOp :: UXTB , ( true , 8 ) => ExtendOp :: SXTB , ( false , 8 ) => ExtendOp :: UXTB , ( true , 16 ) => ExtendOp :: SXTH , ( false , 16 ) => ExtendOp :: UXTH , ( true , 32 ) => ExtendOp :: SXTW , ( false , 32 ) => ExtendOp :: UXTW , _ => unreachable ! ( ) , } ; let reg = input_to_reg ( ctx , extendee , NarrowValueMode :: None ) ; ctx . merged ( insn ) ; return ResultRSE :: RegExtend ( reg , extendop ) ; } } ResultRSE :: from_rs ( input_to_rs ( ctx , input , narrow_mode ) ) }
Lower an instruction input to a reg or reg/shift, or reg/extend operand.
Lower an instruction input to a reg or reg / shift or reg / extend operand .
ctx
&mut C
input
InsnInput
narrow_mode
NarrowValueMode