arm64: Implement Icmp for I16X8 and I32X4
Copyright (c) 2020, Arm Limited.
This commit is contained in:
2
build.rs
2
build.rs
@@ -182,6 +182,8 @@ fn ignore(testsuite: &str, testname: &str, strategy: &str) -> bool {
|
|||||||
"Cranelift" => match (testsuite, testname) {
|
"Cranelift" => match (testsuite, testname) {
|
||||||
("simd", "simd_i8x16_cmp") => return false,
|
("simd", "simd_i8x16_cmp") => return false,
|
||||||
("simd", "simd_store") => return false,
|
("simd", "simd_store") => return false,
|
||||||
|
("simd", "simd_i16x8_cmp") => return false,
|
||||||
|
("simd", "simd_i32x4_cmp") => return false,
|
||||||
// Most simd tests are known to fail on aarch64 for now, it's going
|
// Most simd tests are known to fail on aarch64 for now, it's going
|
||||||
// to be a big chunk of work to implement them all there!
|
// to be a big chunk of work to implement them all there!
|
||||||
("simd", _) if target.contains("aarch64") => return true,
|
("simd", _) if target.contains("aarch64") => return true,
|
||||||
|
|||||||
@@ -406,7 +406,15 @@ fn in_int_reg(ty: ir::Type) -> bool {
|
|||||||
|
|
||||||
fn in_vec_reg(ty: ir::Type) -> bool {
|
fn in_vec_reg(ty: ir::Type) -> bool {
|
||||||
match ty {
|
match ty {
|
||||||
types::F32 | types::F64 | types::I8X16 | types::I16X8 | types::I32X4 | types::I64X2 => true,
|
types::F32 | types::F64 => true,
|
||||||
|
types::B8X16
|
||||||
|
| types::I8X16
|
||||||
|
| types::B16X8
|
||||||
|
| types::I16X8
|
||||||
|
| types::B32X4
|
||||||
|
| types::I32X4
|
||||||
|
| types::B64X2
|
||||||
|
| types::I64X2 => true,
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1175,6 +1175,8 @@ impl MachInstEmit for Inst {
|
|||||||
} => {
|
} => {
|
||||||
let enc_size_for_cmp = match ty {
|
let enc_size_for_cmp = match ty {
|
||||||
I8X16 => 0b00,
|
I8X16 => 0b00,
|
||||||
|
I16X8 => 0b01,
|
||||||
|
I32X4 => 0b10,
|
||||||
_ => 0,
|
_ => 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1985,6 +1985,126 @@ fn test_aarch64_binemit() {
|
|||||||
"cmhs v8.16b, v2.16b, v15.16b",
|
"cmhs v8.16b, v2.16b, v15.16b",
|
||||||
));
|
));
|
||||||
|
|
||||||
|
insns.push((
|
||||||
|
Inst::VecRRR {
|
||||||
|
alu_op: VecALUOp::Cmeq,
|
||||||
|
rd: writable_vreg(3),
|
||||||
|
rn: vreg(23),
|
||||||
|
rm: vreg(24),
|
||||||
|
ty: I16X8,
|
||||||
|
},
|
||||||
|
"E38E786E",
|
||||||
|
"cmeq v3.8h, v23.8h, v24.8h",
|
||||||
|
));
|
||||||
|
|
||||||
|
insns.push((
|
||||||
|
Inst::VecRRR {
|
||||||
|
alu_op: VecALUOp::Cmgt,
|
||||||
|
rd: writable_vreg(3),
|
||||||
|
rn: vreg(23),
|
||||||
|
rm: vreg(24),
|
||||||
|
ty: I16X8,
|
||||||
|
},
|
||||||
|
"E336784E",
|
||||||
|
"cmgt v3.8h, v23.8h, v24.8h",
|
||||||
|
));
|
||||||
|
|
||||||
|
insns.push((
|
||||||
|
Inst::VecRRR {
|
||||||
|
alu_op: VecALUOp::Cmge,
|
||||||
|
rd: writable_vreg(23),
|
||||||
|
rn: vreg(9),
|
||||||
|
rm: vreg(12),
|
||||||
|
ty: I16X8,
|
||||||
|
},
|
||||||
|
"373D6C4E",
|
||||||
|
"cmge v23.8h, v9.8h, v12.8h",
|
||||||
|
));
|
||||||
|
|
||||||
|
insns.push((
|
||||||
|
Inst::VecRRR {
|
||||||
|
alu_op: VecALUOp::Cmhi,
|
||||||
|
rd: writable_vreg(5),
|
||||||
|
rn: vreg(1),
|
||||||
|
rm: vreg(1),
|
||||||
|
ty: I16X8,
|
||||||
|
},
|
||||||
|
"2534616E",
|
||||||
|
"cmhi v5.8h, v1.8h, v1.8h",
|
||||||
|
));
|
||||||
|
|
||||||
|
insns.push((
|
||||||
|
Inst::VecRRR {
|
||||||
|
alu_op: VecALUOp::Cmhs,
|
||||||
|
rd: writable_vreg(8),
|
||||||
|
rn: vreg(2),
|
||||||
|
rm: vreg(15),
|
||||||
|
ty: I16X8,
|
||||||
|
},
|
||||||
|
"483C6F6E",
|
||||||
|
"cmhs v8.8h, v2.8h, v15.8h",
|
||||||
|
));
|
||||||
|
|
||||||
|
insns.push((
|
||||||
|
Inst::VecRRR {
|
||||||
|
alu_op: VecALUOp::Cmeq,
|
||||||
|
rd: writable_vreg(3),
|
||||||
|
rn: vreg(23),
|
||||||
|
rm: vreg(24),
|
||||||
|
ty: I32X4,
|
||||||
|
},
|
||||||
|
"E38EB86E",
|
||||||
|
"cmeq v3.4s, v23.4s, v24.4s",
|
||||||
|
));
|
||||||
|
|
||||||
|
insns.push((
|
||||||
|
Inst::VecRRR {
|
||||||
|
alu_op: VecALUOp::Cmgt,
|
||||||
|
rd: writable_vreg(3),
|
||||||
|
rn: vreg(23),
|
||||||
|
rm: vreg(24),
|
||||||
|
ty: I32X4,
|
||||||
|
},
|
||||||
|
"E336B84E",
|
||||||
|
"cmgt v3.4s, v23.4s, v24.4s",
|
||||||
|
));
|
||||||
|
|
||||||
|
insns.push((
|
||||||
|
Inst::VecRRR {
|
||||||
|
alu_op: VecALUOp::Cmge,
|
||||||
|
rd: writable_vreg(23),
|
||||||
|
rn: vreg(9),
|
||||||
|
rm: vreg(12),
|
||||||
|
ty: I32X4,
|
||||||
|
},
|
||||||
|
"373DAC4E",
|
||||||
|
"cmge v23.4s, v9.4s, v12.4s",
|
||||||
|
));
|
||||||
|
|
||||||
|
insns.push((
|
||||||
|
Inst::VecRRR {
|
||||||
|
alu_op: VecALUOp::Cmhi,
|
||||||
|
rd: writable_vreg(5),
|
||||||
|
rn: vreg(1),
|
||||||
|
rm: vreg(1),
|
||||||
|
ty: I32X4,
|
||||||
|
},
|
||||||
|
"2534A16E",
|
||||||
|
"cmhi v5.4s, v1.4s, v1.4s",
|
||||||
|
));
|
||||||
|
|
||||||
|
insns.push((
|
||||||
|
Inst::VecRRR {
|
||||||
|
alu_op: VecALUOp::Cmhs,
|
||||||
|
rd: writable_vreg(8),
|
||||||
|
rn: vreg(2),
|
||||||
|
rm: vreg(15),
|
||||||
|
ty: I32X4,
|
||||||
|
},
|
||||||
|
"483CAF6E",
|
||||||
|
"cmhs v8.4s, v2.4s, v15.4s",
|
||||||
|
));
|
||||||
|
|
||||||
insns.push((
|
insns.push((
|
||||||
Inst::VecMisc {
|
Inst::VecMisc {
|
||||||
op: VecMisc2::Not,
|
op: VecMisc2::Not,
|
||||||
|
|||||||
@@ -5,8 +5,8 @@
|
|||||||
|
|
||||||
use crate::binemit::CodeOffset;
|
use crate::binemit::CodeOffset;
|
||||||
use crate::ir::types::{
|
use crate::ir::types::{
|
||||||
B1, B16, B32, B64, B8, B8X16, F32, F32X2, F64, FFLAGS, I128, I16, I16X4, I16X8, I32, I32X2,
|
B1, B16, B16X8, B32, B32X4, B64, B64X2, B8, B8X16, F32, F32X2, F64, FFLAGS, I128, I16, I16X4,
|
||||||
I32X4, I64, I64X2, I8, I8X16, I8X8, IFLAGS,
|
I16X8, I32, I32X2, I32X4, I64, I64X2, I8, I8X16, I8X8, IFLAGS,
|
||||||
};
|
};
|
||||||
use crate::ir::{ExternalName, Opcode, SourceLoc, TrapCode, Type};
|
use crate::ir::{ExternalName, Opcode, SourceLoc, TrapCode, Type};
|
||||||
use crate::machinst::*;
|
use crate::machinst::*;
|
||||||
@@ -1977,8 +1977,7 @@ impl MachInst for Inst {
|
|||||||
I8 | I16 | I32 | I64 | B1 | B8 | B16 | B32 | B64 => Ok(RegClass::I64),
|
I8 | I16 | I32 | I64 | B1 | B8 | B16 | B32 | B64 => Ok(RegClass::I64),
|
||||||
F32 | F64 => Ok(RegClass::V128),
|
F32 | F64 => Ok(RegClass::V128),
|
||||||
IFLAGS | FFLAGS => Ok(RegClass::I64),
|
IFLAGS | FFLAGS => Ok(RegClass::I64),
|
||||||
I8X16 | I16X8 | I32X4 | I64X2 => Ok(RegClass::V128),
|
B8X16 | I8X16 | B16X8 | I16X8 | B32X4 | I32X4 | B64X2 | I64X2 => Ok(RegClass::V128),
|
||||||
B8X16 => Ok(RegClass::V128),
|
|
||||||
_ => Err(CodegenError::Unsupported(format!(
|
_ => Err(CodegenError::Unsupported(format!(
|
||||||
"Unexpected SSA-value type: {}",
|
"Unexpected SSA-value type: {}",
|
||||||
ty
|
ty
|
||||||
|
|||||||
@@ -320,12 +320,12 @@ pub fn show_vreg_vector(reg: Reg, mb_rru: Option<&RealRegUniverse>, ty: Type) ->
|
|||||||
|
|
||||||
match ty {
|
match ty {
|
||||||
I8X16 => s.push_str(".16b"),
|
I8X16 => s.push_str(".16b"),
|
||||||
|
I16X8 => s.push_str(".8h"),
|
||||||
|
I32X4 => s.push_str(".4s"),
|
||||||
F32X2 => s.push_str(".2s"),
|
F32X2 => s.push_str(".2s"),
|
||||||
I8X8 => s.push_str(".8b"),
|
I8X8 => s.push_str(".8b"),
|
||||||
I16X4 => s.push_str(".4h"),
|
I16X4 => s.push_str(".4h"),
|
||||||
I16X8 => s.push_str(".8h"),
|
|
||||||
I32X2 => s.push_str(".2s"),
|
I32X2 => s.push_str(".2s"),
|
||||||
I32X4 => s.push_str(".4s"),
|
|
||||||
I64X2 => s.push_str(".2d"),
|
I64X2 => s.push_str(".2d"),
|
||||||
_ => unimplemented!(),
|
_ => unimplemented!(),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -716,8 +716,8 @@ pub fn ty_bits(ty: Type) -> usize {
|
|||||||
B64 | I64 | F64 => 64,
|
B64 | I64 | F64 => 64,
|
||||||
B128 | I128 => 128,
|
B128 | I128 => 128,
|
||||||
IFLAGS | FFLAGS => 32,
|
IFLAGS | FFLAGS => 32,
|
||||||
I8X8 | I16X4 | I32X2 => 64,
|
B8X8 | I8X8 | B16X4 | I16X4 | B32X2 | I32X2 => 64,
|
||||||
B8X16 | I8X16 | I16X8 | I32X4 | I64X2 => 128,
|
B8X16 | I8X16 | B16X8 | I16X8 | B32X4 | I32X4 | B64X2 | I64X2 => 128,
|
||||||
_ => panic!("ty_bits() on unknown type: {:?}", ty),
|
_ => panic!("ty_bits() on unknown type: {:?}", ty),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1193,12 +1193,15 @@ pub(crate) fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
|
|||||||
ctx.emit(alu_inst_imm12(alu_op, writable_zero_reg(), rn, rm));
|
ctx.emit(alu_inst_imm12(alu_op, writable_zero_reg(), rn, rm));
|
||||||
ctx.emit(Inst::CondSet { cond, rd });
|
ctx.emit(Inst::CondSet { cond, rd });
|
||||||
} else {
|
} else {
|
||||||
if ty != I8X16 {
|
match ty {
|
||||||
return Err(CodegenError::Unsupported(format!(
|
I8X16 | I16X8 | I32X4 => {}
|
||||||
"unsupported simd type: {:?}",
|
_ => {
|
||||||
ty
|
return Err(CodegenError::Unsupported(format!(
|
||||||
)));
|
"unsupported simd type: {:?}",
|
||||||
}
|
ty
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
let mut rn = input_to_reg(ctx, inputs[0], narrow_mode);
|
let mut rn = input_to_reg(ctx, inputs[0], narrow_mode);
|
||||||
let mut rm = input_to_reg(ctx, inputs[1], narrow_mode);
|
let mut rm = input_to_reg(ctx, inputs[1], narrow_mode);
|
||||||
|
|||||||
Reference in New Issue
Block a user