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.
This commit is contained in:
@@ -1662,7 +1662,7 @@ pub(crate) fn emit(
|
|||||||
SseOpcode::Paddb => (LegacyPrefix::_66, 0x0FFC),
|
SseOpcode::Paddb => (LegacyPrefix::_66, 0x0FFC),
|
||||||
SseOpcode::Paddd => (LegacyPrefix::_66, 0x0FFE),
|
SseOpcode::Paddd => (LegacyPrefix::_66, 0x0FFE),
|
||||||
SseOpcode::Paddq => (LegacyPrefix::_66, 0x0FD4),
|
SseOpcode::Paddq => (LegacyPrefix::_66, 0x0FD4),
|
||||||
SSeOpcode::Paddw => (LegacyPrefix::_66, 0x0FFD),
|
SseOpcode::Paddw => (LegacyPrefix::_66, 0x0FFD),
|
||||||
SseOpcode::Subps => (LegacyPrefix::None, 0x0F5C),
|
SseOpcode::Subps => (LegacyPrefix::None, 0x0F5C),
|
||||||
SseOpcode::Subpd => (LegacyPrefix::_66, 0x0F5C),
|
SseOpcode::Subpd => (LegacyPrefix::_66, 0x0F5C),
|
||||||
SseOpcode::Subss => (LegacyPrefix::_F3, 0x0F5C),
|
SseOpcode::Subss => (LegacyPrefix::_F3, 0x0F5C),
|
||||||
|
|||||||
@@ -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<u64> {
|
fn iri_to_u64_imm(ctx: Ctx, inst: IRInst) -> Option<u64> {
|
||||||
ctx.get_constant(inst)
|
ctx.get_constant(inst)
|
||||||
}
|
}
|
||||||
@@ -346,28 +338,45 @@ fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
|
|||||||
| Opcode::Band
|
| Opcode::Band
|
||||||
| Opcode::Bor
|
| Opcode::Bor
|
||||||
| Opcode::Bxor => {
|
| 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
|
// TODO For commutative operations (add, mul, and, or, xor), try to commute the
|
||||||
// operands if one is an immediate.
|
// 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);
|
// Move the `lhs` to the same register as `dst`.
|
||||||
let is_64 = int_ty_is_64(ty.unwrap());
|
ctx.emit(Inst::gen_move(dst, lhs, ty));
|
||||||
let alu_op = match op {
|
ctx.emit(Inst::xmm_rm_r(sse_op, rhs, dst));
|
||||||
Opcode::Iadd | Opcode::IaddIfcout => AluRmiROpcode::Add,
|
} else {
|
||||||
Opcode::Isub => AluRmiROpcode::Sub,
|
let is_64 = ty == types::I64;
|
||||||
Opcode::Imul => AluRmiROpcode::Mul,
|
let alu_op = match op {
|
||||||
Opcode::Band => AluRmiROpcode::And,
|
Opcode::Iadd | Opcode::IaddIfcout => AluRmiROpcode::Add,
|
||||||
Opcode::Bor => AluRmiROpcode::Or,
|
Opcode::Isub => AluRmiROpcode::Sub,
|
||||||
Opcode::Bxor => AluRmiROpcode::Xor,
|
Opcode::Imul => AluRmiROpcode::Mul,
|
||||||
_ => unreachable!(),
|
Opcode::Band => AluRmiROpcode::And,
|
||||||
};
|
Opcode::Bor => AluRmiROpcode::Or,
|
||||||
|
Opcode::Bxor => AluRmiROpcode::Xor,
|
||||||
ctx.emit(Inst::mov_r_r(true, lhs, dst));
|
_ => unreachable!(),
|
||||||
ctx.emit(Inst::alu_rmi_r(is_64, alu_op, rhs, dst));
|
};
|
||||||
|
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 => {
|
Opcode::Ishl | Opcode::Ushr | Opcode::Sshr | Opcode::Rotl | Opcode::Rotr => {
|
||||||
|
|||||||
Reference in New Issue
Block a user