/// Lower an instruction input to a reg.
///
/// The given register will be extended appropriately, according to
/// `narrow_mode` and the input's type. If extended, the value is
/// always extended to 64 bits, for simplicity.
Lower an instruction input to a reg.
The given register will be extended appropriately, according to
`narrow_mode` and the input's type. If extended, the value is
always extended to 64 bits, for simplicity.
Lower an instruction input to a reg . The given register will be extended appropriately according to ` narrow_mode ` and the input ' s type . If extended the value is always extended to 64 bits for simplicity .
pub(crate) fn put_input_in_reg<C: LowerCtx<I = Inst>>(
    ctx: &mut C,
    input: InsnInput,
    narrow_mode: NarrowValueMode,
) -> Reg {
    debug!("put_input_in_reg: input {:?}", input);
    let ty = ctx.input_ty(input.insn, input.input);
    let from_bits = ty_bits(ty) as u8;
    let inputs = ctx.get_input(input.insn, input.input);
    let in_reg = if let Some(c) = inputs.constant {
        // Generate constants fresh at each use to minimize long-range register pressure.
        let masked = if from_bits < 64 {
            c & ((1u64 << from_bits) - 1)
        } else {
            c
        };
        let to_reg = ctx.alloc_tmp(Inst::rc_for_type(ty).unwrap(), ty);
        for inst in Inst::gen_constant(to_reg, masked, ty, |reg_class, ty| {
            ctx.alloc_tmp(reg_class, ty)
        })
        .into_iter()
        {
            ctx.emit(inst);
        }
        to_reg.to_reg()
    } else {
        ctx.use_input_reg(inputs);
        inputs.reg
    };
    match (narrow_mode, from_bits) {
        (NarrowValueMode::None, _) => in_reg,
        (NarrowValueMode::ZeroExtend32, n) if n < 32 => {
            let tmp = ctx.alloc_tmp(RegClass::I64, I32);
            ctx.emit(Inst::Extend {
                rd: tmp,
                rn: in_reg,
                signed: false,
                from_bits,
                to_bits: 32,
            });
            tmp.to_reg()
        }
        (NarrowValueMode::SignExtend32, n) if n < 32 => {
            let tmp = ctx.alloc_tmp(RegClass::I64, I32);
            ctx.emit(Inst::Extend {
                rd: tmp,
                rn: in_reg,
                signed: true,
                from_bits,
                to_bits: 32,
            });
            tmp.to_reg()
        }
        (NarrowValueMode::ZeroExtend32, 32) | (NarrowValueMode::SignExtend32, 32) => in_reg,
        (NarrowValueMode::ZeroExtend64, n) if n < 64 => {
            if inputs.constant.is_some() {
                // Constants are zero-extended to full 64-bit width on load already.
                in_reg
            } else {
                let tmp = ctx.alloc_tmp(RegClass::I64, I32);
                ctx.emit(Inst::Extend {
                    rd: tmp,
                    rn: in_reg,
                    signed: false,
                    from_bits,
                    to_bits: 64,
                });
                tmp.to_reg()
            }
        }
        (NarrowValueMode::SignExtend64, n) if n < 64 => {
            let tmp = ctx.alloc_tmp(RegClass::I64, I32);
            ctx.emit(Inst::Extend {
                rd: tmp,
                rn: in_reg,
                signed: true,
                from_bits,
                to_bits: 64,
            });
            tmp.to_reg()
        }
        (_, 64) => in_reg,
        (_, 128) => in_reg,
        _ => panic!(
            "Unsupported input width: input ty {} bits {} mode {:?}",
            ty, from_bits, narrow_mode
        ),
    }
}
pub ( crate ) fn put_input_in_reg < C : LowerCtx < I = Inst > > ( ctx : & mut C , input : InsnInput , narrow_mode : NarrowValueMode , ) -> Reg { debug ! ( " " input ) ; let ty = ctx . input_ty ( input . insn , input . input ) ; let from_bits = ty_bits ( ty ) as u8 ; let inputs = ctx . get_input ( input . insn , input . input ) ; let in_reg = if let Some ( c ) = inputs . constant { // Generate constants fresh at each use to minimize long-range register pressure. let masked = if from_bits < 64 { c & ( ( 1u64 << from_bits ) - 1 ) } else { c } ; let to_reg = ctx . alloc_tmp ( Inst :: rc_for_type ( ty ) . unwrap ( ) , ty ) ; for inst in Inst :: gen_constant ( to_reg , masked , ty , | reg_class , ty | { ctx . alloc_tmp ( reg_class , ty ) } ) . into_iter ( ) { ctx . emit ( inst ) ; } to_reg . to_reg ( ) } else { ctx . use_input_reg ( inputs ) ; inputs . reg } ; match ( narrow_mode , from_bits ) { ( NarrowValueMode :: None , _ ) => in_reg , ( NarrowValueMode :: ZeroExtend32 , n ) if n < 32 => { let tmp = ctx . alloc_tmp ( RegClass :: I64 , I32 ) ; ctx . emit ( Inst :: Extend { rd : tmp , rn : in_reg , signed : false , from_bits , to_bits : 32 , } ) ; tmp . to_reg ( ) } ( NarrowValueMode :: SignExtend32 , n ) if n < 32 => { let tmp = ctx . alloc_tmp ( RegClass :: I64 , I32 ) ; ctx . emit ( Inst :: Extend { rd : tmp , rn : in_reg , signed : true , from_bits , to_bits : 32 , } ) ; tmp . to_reg ( ) } ( NarrowValueMode :: ZeroExtend32 , 32 ) | ( NarrowValueMode :: SignExtend32 , 32 ) => in_reg , ( NarrowValueMode :: ZeroExtend64 , n ) if n < 64 => { if inputs . constant . is_some ( ) { // Constants are zero-extended to full 64-bit width on load already. in_reg } else { let tmp = ctx . alloc_tmp ( RegClass :: I64 , I32 ) ; ctx . emit ( Inst :: Extend { rd : tmp , rn : in_reg , signed : false , from_bits , to_bits : 64 , } ) ; tmp . to_reg ( ) } } ( NarrowValueMode :: SignExtend64 , n ) if n < 64 => { let tmp = ctx . alloc_tmp ( RegClass :: I64 , I32 ) ; ctx . emit ( Inst :: Extend { rd : tmp , rn : in_reg , signed : true , from_bits , to_bits : 64 , } ) ; tmp . to_reg ( ) } ( _ , 64 ) => in_reg , ( _ , 128 ) => in_reg , _ => panic ! ( " " ty from_bits narrow_mode ) , } }
Lower an instruction input to a reg.
Lower an instruction input to a reg .
ctx
&mut C
input
InsnInput
narrow_mode
NarrowValueMode