/// Lower the address of a load or store.
Lower the address of a load or store.
Lower the address of a load or store .
fn lower_address<C: LowerCtx<Inst>>(
    ctx: &mut C,
    elem_ty: Type,
    addends: &[InsnInput],
    offset: i32,
) -> MemArg {
    // TODO: support base_reg + scale * index_reg. For this, we would need to pattern-match shl or
    // mul instructions (Load/StoreComplex don't include scale factors).
    // Handle one reg and offset that fits in immediate, if possible.
    if addends.len() == 1 {
        let reg = input_to_reg(ctx, addends[0], NarrowValueMode::ZeroExtend64);
        if let Some(memarg) = MemArg::reg_maybe_offset(reg, offset as i64, elem_ty) {
            return memarg;
        }
    }
    // Handle two regs and a zero offset, if possible.
    if addends.len() == 2 && offset == 0 {
        let ra = input_to_reg(ctx, addends[0], NarrowValueMode::ZeroExtend64);
        let rb = input_to_reg(ctx, addends[1], NarrowValueMode::ZeroExtend64);
        return MemArg::reg_reg(ra, rb);
    }
    // Otherwise, generate add instructions.
    let addr = ctx.tmp(RegClass::I64, I64);
    // Get the const into a reg.
    lower_constant(ctx, addr.clone(), offset as u64);
    // Add each addend to the address.
    for addend in addends {
        let reg = input_to_reg(ctx, *addend, NarrowValueMode::ZeroExtend64);
        ctx.emit(Inst::AluRRR {
            alu_op: ALUOp::Add64,
            rd: addr.clone(),
            rn: addr.to_reg(),
            rm: reg.clone(),
        });
    }
    MemArg::reg(addr.to_reg())
}
fn lower_address < C : LowerCtx < Inst > > ( ctx : & mut C , elem_ty : Type , addends : & [ InsnInput ] , offset : i32 , ) -> MemArg { // TODO: support base_reg + scale * index_reg. For this, we would need to pattern-match shl or // mul instructions (Load/StoreComplex don't include scale factors). // Handle one reg and offset that fits in immediate, if possible. if addends . len ( ) == 1 { let reg = input_to_reg ( ctx , addends [ 0 ] , NarrowValueMode :: ZeroExtend64 ) ; if let Some ( memarg ) = MemArg :: reg_maybe_offset ( reg , offset as i64 , elem_ty ) { return memarg ; } } // Handle two regs and a zero offset, if possible. if addends . len ( ) == 2 && offset == 0 { let ra = input_to_reg ( ctx , addends [ 0 ] , NarrowValueMode :: ZeroExtend64 ) ; let rb = input_to_reg ( ctx , addends [ 1 ] , NarrowValueMode :: ZeroExtend64 ) ; return MemArg :: reg_reg ( ra , rb ) ; } // Otherwise, generate add instructions. let addr = ctx . tmp ( RegClass :: I64 , I64 ) ; // Get the const into a reg. lower_constant ( ctx , addr . clone ( ) , offset as u64 ) ; // Add each addend to the address. for addend in addends { let reg = input_to_reg ( ctx , * addend , NarrowValueMode :: ZeroExtend64 ) ; ctx . emit ( Inst :: AluRRR { alu_op : ALUOp :: Add64 , rd : addr . clone ( ) , rn : addr . to_reg ( ) , rm : reg . clone ( ) , } ) ; } MemArg :: reg ( addr . to_reg ( ) ) }
Lower the address of a load or store.
Lower the address of a load or store .
ctx
&mut C
elem_ty
Type
addends
&[InsnInput]
offset
i32