/// Emit an instruction to insert a value `src` into a lane of `dst`.
Emit an instruction to insert a value `src` into a lane of `dst`.
Emit an instruction to insert a value ` src ` into a lane of ` dst ` .
fn emit_insert_lane<C: LowerCtx<I = Inst>>(
    ctx: &mut C,
    src: RegMem,
    dst: Writable<Reg>,
    lane: u8,
    ty: Type,
    srcloc: Option<SourceLoc>,
) {
    if !ty.is_float() {
        let (sse_op, is64) = match ty.lane_bits() {
            8 => (SseOpcode::Pinsrb, false),
            16 => (SseOpcode::Pinsrw, false),
            32 => (SseOpcode::Pinsrd, false),
            64 => (SseOpcode::Pinsrd, true),
            _ => panic!("Unable to insertlane for lane size: {}", ty.lane_bits()),
        };
        ctx.emit(Inst::xmm_rm_r_imm(sse_op, src, dst, lane, is64, srcloc));
    } else if ty == types::F32 {
        let sse_op = SseOpcode::Insertps;
        // Insert 32-bits from replacement (at index 00, bits 7:8) to vector (lane
        // shifted into bits 5:6).
        let lane = 0b00_00_00_00 | lane << 4;
        ctx.emit(Inst::xmm_rm_r_imm(sse_op, src, dst, lane, false, srcloc));
    } else if ty == types::F64 {
        let sse_op = match lane {
            // Move the lowest quadword in replacement to vector without changing
            // the upper bits.
            0 => SseOpcode::Movsd,
            // Move the low 64 bits of replacement vector to the high 64 bits of the
            // vector.
            1 => SseOpcode::Movlhps,
            _ => unreachable!(),
        };
        // Here we use the `xmm_rm_r` encoding because it correctly tells the register
        // allocator how we are using `dst`: we are using `dst` as a `mod` whereas other
        // encoding formats like `xmm_unary_rm_r` treat it as a `def`.
        ctx.emit(Inst::xmm_rm_r(sse_op, src, dst, srcloc));
    } else {
        panic!("unable to emit insertlane for type: {}", ty)
    }
}
fn emit_insert_lane < C : LowerCtx < I = Inst > > ( ctx : & mut C , src : RegMem , dst : Writable < Reg > , lane : u8 , ty : Type , srcloc : Option < SourceLoc > , ) { if ! ty . is_float ( ) { let ( sse_op , is64 ) = match ty . lane_bits ( ) { 8 => ( SseOpcode :: Pinsrb , false ) , 16 => ( SseOpcode :: Pinsrw , false ) , 32 => ( SseOpcode :: Pinsrd , false ) , 64 => ( SseOpcode :: Pinsrd , true ) , _ => panic ! ( " " ty lane_bits ( ) ) , } ; ctx . emit ( Inst :: xmm_rm_r_imm ( sse_op , src , dst , lane , is64 , srcloc ) ) ; } else if ty == types :: F32 { let sse_op = SseOpcode :: Insertps ; // Insert 32-bits from replacement (at index 00, bits 7:8) to vector (lane // shifted into bits 5:6). let lane = 0b00_00_00_00 | lane << 4 ; ctx . emit ( Inst :: xmm_rm_r_imm ( sse_op , src , dst , lane , false , srcloc ) ) ; } else if ty == types :: F64 { let sse_op = match lane { // Move the lowest quadword in replacement to vector without changing // the upper bits. 0 => SseOpcode :: Movsd , // Move the low 64 bits of replacement vector to the high 64 bits of the // vector. 1 => SseOpcode :: Movlhps , _ => unreachable ! ( ) , } ; // Here we use the `xmm_rm_r` encoding because it correctly tells the register // allocator how we are using `dst`: we are using `dst` as a `mod` whereas other // encoding formats like `xmm_unary_rm_r` treat it as a `def`. ctx . emit ( Inst :: xmm_rm_r ( sse_op , src , dst , srcloc ) ) ; } else { panic ! ( " " ty ) } }
Emit an instruction to insert a value `src` into a lane of `dst`.
Emit an instruction to insert a value ` src ` into a lane of ` dst ` .
ctx
&mut C
src
RegMem
dst
Writable<Reg>
lane
u8
ty
Type
srcloc
Option<SourceLoc>