@@ -5014,28 +5014,91 @@ fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
50145014 Opcode :: Snarrow | Opcode :: Unarrow => {
50155015 let input_ty = ctx. input_ty ( insn, 0 ) ;
50165016 let output_ty = ctx. output_ty ( insn, 0 ) ;
5017- let src1 = put_input_in_reg ( ctx, inputs[ 0 ] ) ;
5018- let src2 = put_input_in_reg ( ctx, inputs[ 1 ] ) ;
50195017 let dst = get_output_reg ( ctx, outputs[ 0 ] ) . only_reg ( ) . unwrap ( ) ;
50205018 if output_ty. is_vector ( ) {
50215019 match op {
50225020 Opcode :: Snarrow => match ( input_ty, output_ty) {
50235021 ( types:: I16X8 , types:: I8X16 ) => {
5022+ let src1 = put_input_in_reg ( ctx, inputs[ 0 ] ) ;
5023+ let src2 = put_input_in_reg ( ctx, inputs[ 1 ] ) ;
50245024 ctx. emit ( Inst :: gen_move ( dst, src1, input_ty) ) ;
50255025 ctx. emit ( Inst :: xmm_rm_r ( SseOpcode :: Packsswb , RegMem :: reg ( src2) , dst) ) ;
50265026 }
50275027 ( types:: I32X4 , types:: I16X8 ) => {
5028+ let src1 = put_input_in_reg ( ctx, inputs[ 0 ] ) ;
5029+ let src2 = put_input_in_reg ( ctx, inputs[ 1 ] ) ;
50285030 ctx. emit ( Inst :: gen_move ( dst, src1, input_ty) ) ;
50295031 ctx. emit ( Inst :: xmm_rm_r ( SseOpcode :: Packssdw , RegMem :: reg ( src2) , dst) ) ;
50305032 }
5033+ // TODO: The type we are expecting as input as actually an F64X2 but the instruction is only defined
5034+ // for integers so here we use I64X2. This is a separate issue that needs to be fixed in instruction.rs.
5035+ ( types:: I64X2 , types:: I32X4 ) => {
5036+ if let Some ( fcvt_inst) =
5037+ matches_input ( ctx, inputs[ 0 ] , Opcode :: FcvtToSintSat )
5038+ {
5039+ //y = i32x4.trunc_sat_f64x2_s_zero(x) is lowered to:
5040+ //MOVE xmm_tmp, xmm_x
5041+ //CMPEQPD xmm_tmp, xmm_x
5042+ //MOVE xmm_y, xmm_x
5043+ //ANDPS xmm_tmp, [wasm_f64x2_splat(2147483647.0)]
5044+ //MINPD xmm_y, xmm_tmp
5045+ //CVTTPD2DQ xmm_y, xmm_y
5046+
5047+ let fcvt_input = InsnInput {
5048+ insn : fcvt_inst,
5049+ input : 0 ,
5050+ } ;
5051+ let src = put_input_in_reg ( ctx, fcvt_input) ;
5052+ ctx. emit ( Inst :: gen_move ( dst, src, input_ty) ) ;
5053+ let tmp1 = ctx. alloc_tmp ( output_ty) . only_reg ( ) . unwrap ( ) ;
5054+ ctx. emit ( Inst :: gen_move ( tmp1, src, input_ty) ) ;
5055+ let cond = FcmpImm :: from ( FloatCC :: Equal ) ;
5056+ ctx. emit ( Inst :: xmm_rm_r_imm (
5057+ SseOpcode :: Cmppd ,
5058+ RegMem :: reg ( src) ,
5059+ tmp1,
5060+ cond. encode ( ) ,
5061+ OperandSize :: Size32 ,
5062+ ) ) ;
5063+
5064+ // 2147483647.0 is equivalent to 0x41DFFFFFFFC00000
5065+ static UMAX_MASK : [ u8 ; 16 ] = [
5066+ 0x00 , 0x00 , 0xC0 , 0xFF , 0xFF , 0xFF , 0xDF , 0x41 , 0x00 , 0x00 ,
5067+ 0xC0 , 0xFF , 0xFF , 0xFF , 0xDF , 0x41 ,
5068+ ] ;
5069+ let umax_const =
5070+ ctx. use_constant ( VCodeConstantData :: WellKnown ( & UMAX_MASK ) ) ;
5071+ let umax_mask = ctx. alloc_tmp ( types:: F64X2 ) . only_reg ( ) . unwrap ( ) ;
5072+ ctx. emit ( Inst :: xmm_load_const ( umax_const, umax_mask, types:: F64X2 ) ) ;
5073+
5074+ //ANDPD xmm_y, [wasm_f64x2_splat(2147483647.0)]
5075+ ctx. emit ( Inst :: xmm_rm_r (
5076+ SseOpcode :: Andps ,
5077+ RegMem :: from ( umax_mask) ,
5078+ tmp1,
5079+ ) ) ;
5080+ ctx. emit ( Inst :: xmm_rm_r ( SseOpcode :: Minpd , RegMem :: from ( tmp1) , dst) ) ;
5081+ ctx. emit ( Inst :: xmm_rm_r (
5082+ SseOpcode :: Cvttpd2dq ,
5083+ RegMem :: from ( dst) ,
5084+ dst,
5085+ ) ) ;
5086+ } else {
5087+ unreachable ! ( ) ;
5088+ }
5089+ }
50315090 _ => unreachable ! ( ) ,
50325091 } ,
50335092 Opcode :: Unarrow => match ( input_ty, output_ty) {
50345093 ( types:: I16X8 , types:: I8X16 ) => {
5094+ let src1 = put_input_in_reg ( ctx, inputs[ 0 ] ) ;
5095+ let src2 = put_input_in_reg ( ctx, inputs[ 1 ] ) ;
50355096 ctx. emit ( Inst :: gen_move ( dst, src1, input_ty) ) ;
50365097 ctx. emit ( Inst :: xmm_rm_r ( SseOpcode :: Packuswb , RegMem :: reg ( src2) , dst) ) ;
50375098 }
50385099 ( types:: I32X4 , types:: I16X8 ) => {
5100+ let src1 = put_input_in_reg ( ctx, inputs[ 0 ] ) ;
5101+ let src2 = put_input_in_reg ( ctx, inputs[ 1 ] ) ;
50395102 ctx. emit ( Inst :: gen_move ( dst, src1, input_ty) ) ;
50405103 ctx. emit ( Inst :: xmm_rm_r ( SseOpcode :: Packusdw , RegMem :: reg ( src2) , dst) ) ;
50415104 }
0 commit comments