From dd6ba5f9d74dd84f9849708073b3dd542da7af7e Mon Sep 17 00:00:00 2001 From: Johnnie Birch <45402135+jlb6740@users.noreply.github.com> Date: Wed, 5 Aug 2020 13:18:12 -0700 Subject: [PATCH] Lower packed integer add instructions (v128) Adds lowering support for packed integer add instructions and helper function for determining if a type for an instruction indicates it is packed. --- cranelift/codegen/src/isa/x64/inst/emit.rs | 2 +- cranelift/codegen/src/isa/x64/lower.rs | 63 ++++++++++++---------- 2 files changed, 37 insertions(+), 28 deletions(-) diff --git a/cranelift/codegen/src/isa/x64/inst/emit.rs b/cranelift/codegen/src/isa/x64/inst/emit.rs index 22c20cc241..d40cbf7b25 100644 --- a/cranelift/codegen/src/isa/x64/inst/emit.rs +++ b/cranelift/codegen/src/isa/x64/inst/emit.rs @@ -1662,7 +1662,7 @@ pub(crate) fn emit( SseOpcode::Paddb => (LegacyPrefix::_66, 0x0FFC), SseOpcode::Paddd => (LegacyPrefix::_66, 0x0FFE), SseOpcode::Paddq => (LegacyPrefix::_66, 0x0FD4), - SSeOpcode::Paddw => (LegacyPrefix::_66, 0x0FFD), + SseOpcode::Paddw => (LegacyPrefix::_66, 0x0FFD), SseOpcode::Subps => (LegacyPrefix::None, 0x0F5C), SseOpcode::Subpd => (LegacyPrefix::_66, 0x0F5C), SseOpcode::Subss => (LegacyPrefix::_F3, 0x0F5C), diff --git a/cranelift/codegen/src/isa/x64/lower.rs b/cranelift/codegen/src/isa/x64/lower.rs index ac58b2b2a0..0fb250f9f8 100644 --- a/cranelift/codegen/src/isa/x64/lower.rs +++ b/cranelift/codegen/src/isa/x64/lower.rs @@ -45,14 +45,6 @@ fn is_bool_ty(ty: Type) -> bool { } } -fn int_ty_is_64(ty: Type) -> bool { - match ty { - types::I8 | types::I16 | types::I32 => false, - types::I64 => true, - _ => panic!("type {} is none of I8, I16, I32 or I64", ty), - } -} - fn iri_to_u64_imm(ctx: Ctx, inst: IRInst) -> Option { ctx.get_constant(inst) } @@ -346,28 +338,45 @@ fn lower_insn_to_regs>( | Opcode::Band | Opcode::Bor | Opcode::Bxor => { - let lhs = input_to_reg(ctx, inputs[0]); - let rhs = input_to_reg_mem_imm(ctx, inputs[1]); - let dst = output_to_reg(ctx, outputs[0]); - let ty = ty.unwrap(); - // TODO For commutative operations (add, mul, and, or, xor), try to commute the // operands if one is an immediate. + let ty = ty.unwrap(); + println!("Type: {}, Ops: {}", ty, op); + if ty.lane_count() > 1 { + let sse_op = match op { + Opcode::Iadd => match ty { + I8x16 => SseOpcode::Paddb, + I16x8 => SseOpcode::Paddw, + I32x4 => SseOpcode::Paddd, + I64x2 => SseOpcode::Paddq, + _ => panic!("Unsupported type for packed Iadd instruction"), + }, + _ => panic!("Unsupported packed instruction"), + }; + let lhs = input_to_reg(ctx, inputs[0]); + let rhs = input_to_reg_mem(ctx, inputs[1]); + let dst = output_to_reg(ctx, outputs[0]); - println!("Type: {}", ty); - let is_64 = int_ty_is_64(ty.unwrap()); - let alu_op = match op { - Opcode::Iadd | Opcode::IaddIfcout => AluRmiROpcode::Add, - Opcode::Isub => AluRmiROpcode::Sub, - Opcode::Imul => AluRmiROpcode::Mul, - Opcode::Band => AluRmiROpcode::And, - Opcode::Bor => AluRmiROpcode::Or, - Opcode::Bxor => AluRmiROpcode::Xor, - _ => unreachable!(), - }; - - ctx.emit(Inst::mov_r_r(true, lhs, dst)); - ctx.emit(Inst::alu_rmi_r(is_64, alu_op, rhs, dst)); + // Move the `lhs` to the same register as `dst`. + ctx.emit(Inst::gen_move(dst, lhs, ty)); + ctx.emit(Inst::xmm_rm_r(sse_op, rhs, dst)); + } else { + let is_64 = ty == types::I64; + let alu_op = match op { + Opcode::Iadd | Opcode::IaddIfcout => AluRmiROpcode::Add, + Opcode::Isub => AluRmiROpcode::Sub, + Opcode::Imul => AluRmiROpcode::Mul, + Opcode::Band => AluRmiROpcode::And, + Opcode::Bor => AluRmiROpcode::Or, + Opcode::Bxor => AluRmiROpcode::Xor, + _ => unreachable!(), + }; + let lhs = input_to_reg(ctx, inputs[0]); + let rhs = input_to_reg_mem_imm(ctx, inputs[1]); + let dst = output_to_reg(ctx, outputs[0]); + ctx.emit(Inst::mov_r_r(true, lhs, dst)); + ctx.emit(Inst::alu_rmi_r(is_64, alu_op, rhs, dst)); + } } Opcode::Ishl | Opcode::Ushr | Opcode::Sshr | Opcode::Rotl | Opcode::Rotr => {