Merge pull request #1854 from akirilov-arm/simd_load_splat

Enable the wast::Cranelift::spec::simd::simd_load_splat test for AArch64
This commit is contained in:
Chris Fallin
2020-06-10 12:11:29 -07:00
committed by GitHub
6 changed files with 164 additions and 8 deletions

View File

@@ -181,10 +181,11 @@ fn ignore(testsuite: &str, testname: &str, strategy: &str) -> bool {
},
"Cranelift" => match (testsuite, testname) {
("simd", "simd_i8x16_cmp") => return false,
("simd", "simd_load_extend") => return false,
("simd", "simd_store") => return false,
("simd", "simd_i16x8_cmp") => return false,
("simd", "simd_i32x4_cmp") => return false,
("simd", "simd_load_extend") => return false,
("simd", "simd_load_splat") => return false,
("simd", "simd_store") => return false,
// 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!
("simd", _) if target.contains("aarch64") => return true,

View File

@@ -1175,6 +1175,34 @@ impl MachInstEmit for Inst {
| machreg_to_gpr(rd.to_reg()),
);
}
&Inst::VecDup { rd, rn, ty } => {
let imm5 = match ty {
I8 => 0b00001,
I16 => 0b00010,
I32 => 0b00100,
I64 => 0b01000,
_ => unimplemented!(),
};
sink.put4(
0b010_01110000_00000_000011_00000_00000
| (imm5 << 16)
| (machreg_to_gpr(rn) << 5)
| machreg_to_vec(rd.to_reg()),
);
}
&Inst::VecDupFromFpu { rd, rn, ty } => {
let imm5 = match ty {
F32 => 0b00100,
F64 => 0b01000,
_ => unimplemented!(),
};
sink.put4(
0b010_01110000_00000_000001_00000_00000
| (imm5 << 16)
| (machreg_to_vec(rn) << 5)
| machreg_to_vec(rd.to_reg()),
);
}
&Inst::VecExtend { t, rd, rn } => {
let (u, immh) = match t {
VecExtendOp::Sxtl8 => (0b0, 0b001),

View File

@@ -1858,6 +1858,60 @@ fn test_aarch64_binemit() {
"E5979F9A",
"cset x5, hi",
));
insns.push((
Inst::VecDup {
rd: writable_vreg(25),
rn: xreg(7),
ty: I8,
},
"F90C014E",
"dup v25.16b, w7",
));
insns.push((
Inst::VecDup {
rd: writable_vreg(2),
rn: xreg(23),
ty: I16,
},
"E20E024E",
"dup v2.8h, w23",
));
insns.push((
Inst::VecDup {
rd: writable_vreg(0),
rn: xreg(28),
ty: I32,
},
"800F044E",
"dup v0.4s, w28",
));
insns.push((
Inst::VecDup {
rd: writable_vreg(31),
rn: xreg(5),
ty: I64,
},
"BF0C084E",
"dup v31.2d, x5",
));
insns.push((
Inst::VecDupFromFpu {
rd: writable_vreg(14),
rn: vreg(19),
ty: F32,
},
"6E06044E",
"dup v14.4s, v19.s[0]",
));
insns.push((
Inst::VecDupFromFpu {
rd: writable_vreg(18),
rn: vreg(10),
ty: F64,
},
"5205084E",
"dup v18.2d, v10.d[0]",
));
insns.push((
Inst::VecExtend {
t: VecExtendOp::Sxtl8,

View File

@@ -5,8 +5,8 @@
use crate::binemit::CodeOffset;
use crate::ir::types::{
B1, B16, B16X8, B32, B32X4, B64, B64X2, B8, B8X16, F32, F32X2, F64, FFLAGS, I128, I16, I16X4,
I16X8, I32, I32X2, I32X4, I64, I64X2, I8, I8X16, I8X8, IFLAGS,
B1, B16, B16X8, B32, B32X4, B64, B64X2, B8, B8X16, F32, F32X2, F32X4, F64, F64X2, FFLAGS, I128,
I16, I16X4, I16X8, I32, I32X2, I32X4, I64, I64X2, I8, I8X16, I8X8, IFLAGS,
};
use crate::ir::{ExternalName, Opcode, SourceLoc, TrapCode, Type};
use crate::machinst::*;
@@ -695,6 +695,20 @@ pub enum Inst {
ty: Type,
},
/// Duplicate general-purpose register to vector.
VecDup {
rd: Writable<Reg>,
rn: Reg,
ty: Type,
},
/// Duplicate scalar to vector.
VecDupFromFpu {
rd: Writable<Reg>,
rn: Reg,
ty: Type,
},
/// Vector extend.
VecExtend {
t: VecExtendOp,
@@ -1247,6 +1261,14 @@ fn aarch64_get_regs(inst: &Inst, collector: &mut RegUsageCollector) {
collector.add_def(rd);
collector.add_use(rn);
}
&Inst::VecDup { rd, rn, .. } => {
collector.add_def(rd);
collector.add_use(rn);
}
&Inst::VecDupFromFpu { rd, rn, .. } => {
collector.add_def(rd);
collector.add_use(rn);
}
&Inst::VecExtend { rd, rn, .. } => {
collector.add_def(rd);
collector.add_use(rn);
@@ -1804,6 +1826,22 @@ fn aarch64_map_regs<RUM: RegUsageMapper>(inst: &mut Inst, mapper: &RUM) {
map_def(mapper, rd);
map_use(mapper, rn);
}
&mut Inst::VecDup {
ref mut rd,
ref mut rn,
..
} => {
map_def(mapper, rd);
map_use(mapper, rn);
}
&mut Inst::VecDupFromFpu {
ref mut rd,
ref mut rn,
..
} => {
map_def(mapper, rd);
map_use(mapper, rn);
}
&mut Inst::VecExtend {
ref mut rd,
ref mut rn,
@@ -2583,6 +2621,28 @@ impl ShowWithRRU for Inst {
let rn = show_vreg_element(rn, mb_rru, idx, ty);
format!("{} {}, {}", op, rd, rn)
}
&Inst::VecDup { rd, rn, ty } => {
let vector_type = match ty {
I8 => I8X16,
I16 => I16X8,
I32 => I32X4,
I64 => I64X2,
_ => unimplemented!(),
};
let rd = show_vreg_vector(rd.to_reg(), mb_rru, vector_type);
let rn = show_ireg_sized(rn, mb_rru, InstSize::from_ty(ty));
format!("dup {}, {}", rd, rn)
}
&Inst::VecDupFromFpu { rd, rn, ty } => {
let vector_type = match ty {
F32 => F32X4,
F64 => F64X2,
_ => unimplemented!(),
};
let rd = show_vreg_vector(rd.to_reg(), mb_rru, vector_type);
let rn = show_vreg_element(rn, mb_rru, 0, ty);
format!("dup {}, {}", rd, rn)
}
&Inst::VecExtend { t, rd, rn } => {
let (op, dest, src) = match t {
VecExtendOp::Sxtl8 => ("sxtl", I16X8, I8X8),

View File

@@ -319,13 +319,15 @@ pub fn show_vreg_vector(reg: Reg, mb_rru: Option<&RealRegUniverse>, ty: Type) ->
let mut s = reg.show_rru(mb_rru);
match ty {
I8X16 => s.push_str(".16b"),
I16X8 => s.push_str(".8h"),
I32X4 => s.push_str(".4s"),
F32X2 => s.push_str(".2s"),
F32X4 => s.push_str(".4s"),
F64X2 => s.push_str(".2d"),
I8X8 => s.push_str(".8b"),
I8X16 => s.push_str(".16b"),
I16X4 => s.push_str(".4h"),
I16X8 => s.push_str(".8h"),
I32X2 => s.push_str(".2s"),
I32X4 => s.push_str(".4s"),
I64X2 => s.push_str(".2d"),
_ => unimplemented!(),
}

View File

@@ -1483,13 +1483,24 @@ pub(crate) fn lower_insn_to_regs<C: LowerCtx<I = Inst>>(
}
}
Opcode::Splat => {
let rn = input_to_reg(ctx, inputs[0], NarrowValueMode::None);
let rd = output_to_reg(ctx, outputs[0]);
let ty = ctx.input_ty(insn, 0);
let inst = if ty_is_int(ty) {
Inst::VecDup { rd, rn, ty }
} else {
Inst::VecDupFromFpu { rd, rn, ty }
};
ctx.emit(inst);
}
Opcode::Shuffle
| Opcode::Vsplit
| Opcode::Vconcat
| Opcode::Vselect
| Opcode::VanyTrue
| Opcode::VallTrue
| Opcode::Splat
| Opcode::Insertlane
| Opcode::ScalarToVector
| Opcode::Swizzle